Flutter Impeller
impeller::testing Namespace Reference

Classes

struct  BlendModeSelection
 
struct  ColorBlendTestData
 
class  CompareFunctionUIData
 
struct  CVTest
 
struct  Foo
 
class  GaussianBlurFilterContentsTest
 
class  GoldenDigest
 Manages a global variable for tracking instances of golden images. More...
 
class  GoldenTests
 
struct  MaskBlurTestConfig
 
class  MetalScreenshot
 A screenshot that was produced from MetalScreenshotter. More...
 
class  MetalScreenshotter
 
class  RendererDartTest
 
struct  RWFoo
 
class  Screenshot
 
class  Screenshotter
 
class  TestAllocator
 
class  TestPassDelegate
 
struct  TextRenderOptions
 
class  VulkanScreenshotter
 
class  WorkingDirectory
 

Typedefs

using AiksTest = AiksPlayground
 
using AiksCanvasTest = ::testing::Test
 
using DisplayListTest = DlPlayground
 
using EntityTest = EntityPlayground
 
using HostBufferTest = EntityPlayground
 
using EntityPassTargetTest = EntityPlayground
 
using RenderTargetCacheTest = EntityPlayground
 
using DriverInfoVKTest = PlaygroundTest
 
using RendererTest = PlaygroundTest
 
using BlitPassTest = PlaygroundTest
 
using ComputeSubgroupTest = ComputePlaygroundTest
 
using ComputeTest = ComputePlaygroundTest
 
using DeviceBufferTest = Playground
 
using RuntimeStageTest = RuntimeStagePlayground
 
using TypographerTest = PlaygroundTest
 

Functions

 TEST_P (AiksTest, CanRenderMaskBlurHugeSigma)
 
 TEST_P (AiksTest, CanRenderForegroundBlendWithMaskBlur)
 
 TEST_P (AiksTest, CanRenderForegroundAdvancedBlendWithMaskBlur)
 
 TEST_P (AiksTest, CanRenderBackdropBlurInteractive)
 
 TEST_P (AiksTest, CanRenderBackdropBlur)
 
 TEST_P (AiksTest, CanRenderBackdropBlurHugeSigma)
 
 TEST_P (AiksTest, CanRenderClippedBlur)
 
 TEST_P (AiksTest, ClippedBlurFilterRendersCorrectlyInteractive)
 
 TEST_P (AiksTest, ClippedBlurFilterRendersCorrectly)
 
 TEST_P (AiksTest, ClearBlendWithBlur)
 
 TEST_P (AiksTest, BlurHasNoEdge)
 
 TEST_P (AiksTest, BlurredRectangleWithShader)
 
 TEST_P (AiksTest, MaskBlurWithZeroSigmaIsSkipped)
 
static Picture MaskBlurVariantTest (const AiksTest &test_context, const MaskBlurTestConfig &config)
 
 TEST_P (AiksTest, GaussianBlurAtPeripheryVertical)
 
 TEST_P (AiksTest, GaussianBlurAtPeripheryHorizontal)
 
 TEST_P (AiksTest, GaussianBlurWithoutDecalSupport)
 
 TEST_P (AiksTest, GaussianBlurOneDimension)
 
 TEST_P (AiksTest, GaussianBlurRotatedAndClipped)
 
 TEST_P (AiksTest, GaussianBlurScaledAndClipped)
 
 TEST_P (AiksTest, GaussianBlurRotatedAndClippedInteractive)
 
 TEST_P (AiksTest, GaussianBlurSolidColorTinyMipMap)
 
 TEST_P (AiksTest, GaussianBlurBackdropTinyMipMap)
 
 TEST_P (AiksTest, GaussianBlurAnimatedBackdrop)
 
 TEST_P (AiksTest, GaussianBlurStyleInnerGradient)
 
 TEST_P (AiksTest, GaussianBlurStyleSolidGradient)
 
 TEST_P (AiksTest, GaussianBlurStyleOuterGradient)
 
 TEST_P (AiksTest, GaussianBlurStyleInner)
 
 TEST_P (AiksTest, GaussianBlurStyleOuter)
 
 TEST_P (AiksTest, GaussianBlurStyleSolid)
 
 TEST_P (AiksTest, MaskBlurTexture)
 
 TEST_P (AiksTest, GuassianBlurUpdatesMipmapContents)
 
 TEST_P (AiksTest, GaussianBlurSetsMipCountOnPass)
 
 TEST_P (AiksTest, GaussianBlurAllocatesCorrectMipCountRenderTarget)
 
 TEST_P (AiksTest, GaussianBlurMipMapNestedLayer)
 
 TEST_P (AiksTest, GaussianBlurMipMapImageFilter)
 
 TEST_P (AiksTest, GaussianBlurMipMapSolidColor)
 
 TEST_P (AiksTest, MaskBlurDoesntStretchContents)
 
 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)
 
 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, GradientStrokesRenderCorrectly)
 
 TEST_P (AiksTest, RotateColorFilteredPath)
 
 TEST_P (AiksTest, CanRenderStrokes)
 
 TEST_P (AiksTest, CanRenderCurvedStrokes)
 
 TEST_P (AiksTest, CanRenderThickCurvedStrokes)
 
 TEST_P (AiksTest, CanRenderStrokePathThatEndsAtSharpTurn)
 
 TEST_P (AiksTest, CanRenderStrokePathWithCubicLine)
 
 TEST_P (AiksTest, CanRenderDifferencePaths)
 
 TEST_P (AiksTest, CanDrawAnOpenPath)
 
 TEST_P (AiksTest, CanDrawAnOpenPathThatIsntARect)
 
 TEST_P (AiksTest, SolidStrokesRenderCorrectly)
 
 TEST_P (AiksTest, DrawLinesRenderCorrectly)
 
 TEST_P (AiksTest, DrawRectStrokesRenderCorrectly)
 
 TEST_P (AiksTest, DrawRectStrokesWithBevelJoinRenderCorrectly)
 
 TEST_P (AiksTest, CanDrawMultiContourConvexPath)
 
 TEST_P (AiksTest, ArcWithZeroSweepAndBlur)
 
 TEST_P (AiksTest, CanRenderClips)
 
 TEST_P (AiksTest, CanRenderOverlappingMultiContourPath)
 
 INSTANTIATE_PLAYGROUND_SUITE (AiksTest)
 
 TEST_P (AiksTest, CanvasCTMCanBeUpdated)
 
 TEST_P (AiksTest, CanvasCanPushPopCTM)
 
 TEST_P (AiksTest, CanRenderColoredRect)
 
 TEST_P (AiksTest, CanRenderImage)
 
 TEST_P (AiksTest, CanRenderInvertedImageWithColorFilter)
 
 TEST_P (AiksTest, CanRenderColorFilterWithInvertColors)
 
 TEST_P (AiksTest, CanRenderColorFilterWithInvertColorsDrawPaint)
 
 TEST_P (AiksTest, CanRenderAdvancedBlendColorFilterWithSaveLayer)
 
 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, CanRenderSimpleClips)
 
 TEST_P (AiksTest, CanRenderNestedClips)
 
 TEST_P (AiksTest, CanRenderDifferenceClips)
 
 TEST_P (AiksTest, CanRenderWithContiguousClipRestores)
 
 TEST_P (AiksTest, ClipsUseCurrentTransform)
 
 TEST_P (AiksTest, CanSaveLayerStandalone)
 
 TEST_P (AiksTest, CanRenderDifferentShapesWithSameColorSource)
 
 TEST_P (AiksTest, CanPictureConvertToImage)
 
 TEST_P (AiksTest, CanEmptyPictureConvertToImage)
 
 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)
 
bool RenderTextInCanvasSkia (const std::shared_ptr< Context > &context, Canvas &canvas, const std::string &text, const std::string_view &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, CanRenderEmojiTextFrameWithBlur)
 
 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, FilledCirclesRenderCorrectly)
 
 TEST_P (AiksTest, StrokedCirclesRenderCorrectly)
 
 TEST_P (AiksTest, FilledEllipsesRenderCorrectly)
 
 TEST_P (AiksTest, FilledRoundRectsRenderCorrectly)
 
 TEST_P (AiksTest, SolidColorCirclesOvalsRRectsMaskBlurCorrectly)
 
 TEST_P (AiksTest, FilledRoundRectPathsRenderCorrectly)
 
 TEST_P (AiksTest, CoverageOriginShouldBeAccountedForInSubpasses)
 
 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 (Vector2 content_scale, 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, ImageFilteredSaveLayerWithUnboundedContents)
 
 TEST_P (AiksTest, ImageFilteredUnboundedSaveLayerWithUnboundedContents)
 
 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, 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, MatrixSaveLayerFilter)
 
 TEST_P (AiksTest, MatrixBackdropFilter)
 
 TEST_P (AiksTest, SolidColorApplyColorFilter)
 
 TEST_P (AiksTest, DrawScaledTextWithPerspectiveNoSaveLayer)
 
 TEST_P (AiksTest, DrawScaledTextWithPerspectiveSaveLayer)
 
 TEST_P (AiksTest, PipelineBlendSingleParameter)
 
 TEST_P (AiksTest, CaptureContext)
 
 TEST_P (AiksTest, CaptureInactivatedByDefault)
 
 TEST_P (AiksTest, ReleasesTextureOnTeardown)
 
 TEST_P (AiksTest, VerticesGeometryUVPositionData)
 
 TEST_P (AiksTest, VerticesGeometryUVPositionDataWithTranslate)
 
 TEST_P (AiksTest, ClearBlend)
 
 TEST_P (AiksTest, MatrixImageFilterMagnify)
 
 TEST_P (AiksTest, MatrixImageFilterDoesntCullWhenTranslatedFromOffscreen)
 
 TEST_P (AiksTest, MatrixImageFilterDoesntCullWhenScaledAndTranslatedFromOffscreen)
 
 TEST_P (AiksTest, ClearColorOptimizationWhenSubpassIsBiggerThanParentPass)
 
 TEST_P (AiksTest, EmptySaveLayerIgnoresPaint)
 
 TEST_P (AiksTest, EmptySaveLayerRendersWithClear)
 
 TEST_P (AiksTest, SubpassWithClearColorOptimization)
 
 TEST_P (AiksTest, ImageColorSourceEffectTransform)
 
 TEST_P (AiksTest, CorrectClipDepthAssignedToEntities)
 
 TEST_P (AiksTest, CanDrawPerspectiveTransformWithClips)
 
 TEST_P (AiksTest, CanRenderClippedBackdropFilter)
 
 TEST (CanvasRecorder, Save)
 
 TEST (CanvasRecorder, SaveLayer)
 
 TEST (CanvasRecorder, Restore)
 
 TEST (CanvasRecorder, RestoreToCount)
 
 TEST (CanvasRecorder, ResetTransform)
 
 TEST (CanvasRecorder, Transform)
 
 TEST (CanvasRecorder, Concat)
 
 TEST (CanvasRecorder, PreConcat)
 
 TEST (CanvasRecorder, Translate)
 
 TEST (CanvasRecorder, Scale2)
 
 TEST (CanvasRecorder, Scale3)
 
 TEST (CanvasRecorder, Skew)
 
 TEST (CanvasRecorder, Rotate)
 
 TEST (CanvasRecorder, DrawPath)
 
 TEST (CanvasRecorder, DrawPaint)
 
 TEST (CanvasRecorder, DrawLine)
 
 TEST (CanvasRecorder, DrawRect)
 
 TEST (CanvasRecorder, DrawOval)
 
 TEST (CanvasRecorder, DrawRRect)
 
 TEST (CanvasRecorder, DrawCircle)
 
 TEST (CanvasRecorder, DrawPoints)
 
 TEST (CanvasRecorder, DrawImage)
 
 TEST (CanvasRecorder, DrawImageRect)
 
 TEST (CanvasRecorder, ClipPath)
 
 TEST (CanvasRecorder, ClipRect)
 
 TEST (CanvasRecorder, ClipOval)
 
 TEST (CanvasRecorder, ClipRRect)
 
 TEST (CanvasRecorder, DrawTextFrame)
 
 TEST (CanvasRecorder, DrawVertices)
 
 TEST (CanvasRecorder, DrawAtlas)
 
 TEST (AiksCanvasTest, EmptyCullRect)
 
 TEST (AiksCanvasTest, InitialCullRect)
 
 TEST (AiksCanvasTest, TranslatedCullRect)
 
 TEST (AiksCanvasTest, ScaledCullRect)
 
 TEST (AiksCanvasTest, RectClipIntersectAgainstEmptyCullRect)
 
 TEST (AiksCanvasTest, RectClipDiffAgainstEmptyCullRect)
 
 TEST (AiksCanvasTest, RectClipIntersectAgainstCullRect)
 
 TEST (AiksCanvasTest, RectClipDiffAgainstNonCoveredCullRect)
 
 TEST (AiksCanvasTest, RectClipDiffAboveCullRect)
 
 TEST (AiksCanvasTest, RectClipDiffBelowCullRect)
 
 TEST (AiksCanvasTest, RectClipDiffLeftOfCullRect)
 
 TEST (AiksCanvasTest, RectClipDiffRightOfCullRect)
 
 TEST (AiksCanvasTest, RectClipDiffAgainstVCoveredCullRect)
 
 TEST (AiksCanvasTest, RectClipDiffAgainstHCoveredCullRect)
 
 TEST (AiksCanvasTest, RRectClipIntersectAgainstEmptyCullRect)
 
 TEST (AiksCanvasTest, RRectClipDiffAgainstEmptyCullRect)
 
 TEST (AiksCanvasTest, RRectClipIntersectAgainstCullRect)
 
 TEST (AiksCanvasTest, RRectClipDiffAgainstNonCoveredCullRect)
 
 TEST (AiksCanvasTest, RRectClipDiffAgainstVPartiallyCoveredCullRect)
 
 TEST (AiksCanvasTest, RRectClipDiffAgainstVFullyCoveredCullRect)
 
 TEST (AiksCanvasTest, RRectClipDiffAgainstHPartiallyCoveredCullRect)
 
 TEST (AiksCanvasTest, RRectClipDiffAgainstHFullyCoveredCullRect)
 
 TEST (AiksCanvasTest, PathClipIntersectAgainstEmptyCullRect)
 
 TEST (AiksCanvasTest, PathClipDiffAgainstEmptyCullRect)
 
 TEST (AiksCanvasTest, PathClipIntersectAgainstCullRect)
 
 TEST (AiksCanvasTest, PathClipDiffAgainstNonCoveredCullRect)
 
 TEST (AiksCanvasTest, PathClipDiffAgainstFullyCoveredCullRect)
 
 TEST (AiksCanvasTest, DisableLocalBoundsRectForFilteredSaveLayers)
 
 TEST (TraceSerializer, Save)
 
 TEST (ThreadTest, CanCreateMutex)
 
 TEST (ThreadTest, CanCreateMutexLock)
 
 TEST (ThreadTest, CanCreateRWMutex)
 
 TEST (ThreadTest, CanCreateRWMutexLock)
 
 TEST (StringsTest, CanSPrintF)
 
 TEST (ConditionVariableTest, WaitUntil)
 
 TEST (ConditionVariableTest, WaitFor)
 
 TEST (ConditionVariableTest, WaitForever)
 
 TEST (ConditionVariableTest, TestsCriticalSectionAfterWaitForUntil)
 
 TEST (ConditionVariableTest, TestsCriticalSectionAfterWait)
 
 TEST (BaseTest, NoExceptionPromiseValue)
 
 TEST (BaseTest, NoExceptionPromiseEmpty)
 
 TEST (BaseTest, CanUseTypedMasks)
 
 TEST (AllocatorTest, TextureDescriptorCompatibility)
 
flutter::DlColor toColor (const float *components)
 
 INSTANTIATE_PLAYGROUND_SUITE (DisplayListTest)
 
 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, NinePatchImagePrecision)
 
 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, ClipDrawRRectWithNonCircularRadii)
 
 TEST_P (DisplayListTest, DrawVerticesBlendModes)
 
template<typename Contents >
static std::optional< RectGetCoverageOfFirstEntity (const Picture &picture)
 
 TEST (DisplayListTest, RRectBoundsComputation)
 
 TEST (DisplayListTest, CircleBoundsComputation)
 
 TEST_P (DisplayListTest, DrawPaintIgnoresMaskFilter)
 
 TEST (SkiaConversionsTest, SkPointToPoint)
 
 TEST (SkiaConversionsTest, SkPointToSize)
 
 TEST (SkiaConversionsTest, ToColor)
 
 TEST (SkiaConversionsTest, GradientStopConversion)
 
 TEST (SkiaConversionsTest, GradientMissing0)
 
 TEST (SkiaConversionsTest, GradientMissingLastValue)
 
 TEST (SkiaConversionsTest, GradientStopGreaterThan1)
 
 TEST (SkiaConversionsTest, GradientConversionNonMonotonic)
 
 TEST (ContentContext, CachesPipelines)
 
 TEST (ContentContext, InvalidatesAllPipelinesWithSameUniqueNameOnClear)
 
 TEST (ContentContext, InitializeCommonlyUsedShadersIfNeeded)
 
 INSTANTIATE_PLAYGROUND_SUITE (GaussianBlurFilterContentsTest)
 
 TEST (GaussianBlurFilterContentsTest, Create)
 
 TEST (GaussianBlurFilterContentsTest, CoverageEmpty)
 
 TEST (GaussianBlurFilterContentsTest, CoverageSimple)
 
 TEST (GaussianBlurFilterContentsTest, CoverageWithSigma)
 
 TEST_P (GaussianBlurFilterContentsTest, CoverageWithTexture)
 
 TEST_P (GaussianBlurFilterContentsTest, CoverageWithEffectTransform)
 
 TEST (GaussianBlurFilterContentsTest, FilterSourceCoverage)
 
 TEST (GaussianBlurFilterContentsTest, CalculateSigmaValues)
 
 TEST_P (GaussianBlurFilterContentsTest, RenderCoverageMatchesGetCoverage)
 
 TEST_P (GaussianBlurFilterContentsTest, RenderCoverageMatchesGetCoverageTranslate)
 
 TEST_P (GaussianBlurFilterContentsTest, RenderCoverageMatchesGetCoverageRotated)
 
 TEST_P (GaussianBlurFilterContentsTest, CalculateUVsSimple)
 
 TEST_P (GaussianBlurFilterContentsTest, TextureContentsWithDestinationRect)
 
 TEST_P (GaussianBlurFilterContentsTest, TextureContentsWithDestinationRectScaled)
 
 TEST_P (GaussianBlurFilterContentsTest, TextureContentsWithEffectTransform)
 
 TEST (GaussianBlurFilterContentsTest, CalculateSigmaForBlurRadius)
 
 TEST (GaussianBlurFilterContentsTest, Coefficients)
 
 TEST (GaussianBlurFilterContentsTest, LerpHackKernelSamplesSimple)
 
 TEST (GaussianBlurFilterContentsTest, LerpHackKernelSamplesComplex)
 
 TEST (FilterInputTest, CanSetLocalTransformForTexture)
 
 TEST (FilterInputTest, IsLeaf)
 
 TEST (FilterInputTest, SetCoverageInputs)
 
 INSTANTIATE_PLAYGROUND_SUITE (HostBufferTest)
 
 TEST_P (HostBufferTest, CanEmplace)
 
 TEST_P (HostBufferTest, CanEmplaceWithAlignment)
 
 TEST_P (HostBufferTest, HostBufferInitialState)
 
 TEST_P (HostBufferTest, ResetIncrementsFrameCounter)
 
 TEST_P (HostBufferTest, EmplacingLargerThanBlockSizeCreatesOneOffBufferCallback)
 
 TEST_P (HostBufferTest, EmplacingLargerThanBlockSizeCreatesOneOffBuffer)
 
 TEST_P (HostBufferTest, UnusedBuffersAreDiscardedWhenResetting)
 
 TEST_P (HostBufferTest, EmplaceWithProcIsAligned)
 
 TEST_P (EntityTest, TiledTextureContentsRendersWithCorrectPipeline)
 
 TEST_P (EntityTest, TiledTextureContentsRendersWithCorrectPipelineExternalOES)
 
std::shared_ptr< VerticesGeometryCreateColorVertices (const std::vector< Point > &vertices, const std::vector< Color > &colors)
 
 TEST_P (EntityTest, RendersDstPerColorWithAlpha)
 
 TEST_P (EntityPassTargetTest, SwapWithMSAATexture)
 
 TEST_P (EntityPassTargetTest, SwapWithMSAAImplicitResolve)
 
 TEST (EntityPassClipStackTest, CanPushAndPopEntities)
 
 TEST (EntityPassClipStackTest, CanPopEntitiesSafely)
 
 TEST (EntityPassClipStackTest, CanAppendNoChange)
 
 TEST (EntityPassClipStackTest, AppendCoverageNoChange)
 
 TEST (EntityPassClipStackTest, AppendAndRestoreClipCoverage)
 
 TEST (EntityPassClipStackTest, UnbalancedRestore)
 
 TEST (EntityPassClipStackTest, ClipAndRestoreWithSubpasses)
 
 TEST_P (EntityTest, CanCreateEntity)
 
auto CreatePassWithRectPath (Rect rect, std::optional< Rect > bounds_hint, ContentBoundsPromise bounds_promise=ContentBoundsPromise::kUnknown, bool collapse=false)
 
 TEST_P (EntityTest, EntityPassRespectsUntrustedSubpassBoundsLimit)
 
 TEST_P (EntityTest, EntityPassTrustsSnugSubpassBoundsLimit)
 
 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, CanDrawCorrectlyWithRotatedTransform)
 
 TEST_P (EntityTest, CubicCurveAndOverlapTest)
 
 TEST_P (EntityTest, SolidColorContentsStrokeSetStrokeCapsAndJoins)
 
 TEST_P (EntityTest, SolidColorContentsStrokeSetMiterLimit)
 
 TEST_P (EntityTest, BlendingModeOptions)
 
 TEST_P (EntityTest, BezierCircleScaled)
 
 TEST_P (EntityTest, Filters)
 
 TEST_P (EntityTest, GaussianBlurFilter)
 
 TEST_P (EntityTest, MorphologyFilter)
 
 TEST_P (EntityTest, SetBlendMode)
 
 TEST_P (EntityTest, ContentsGetBoundsForEmptyPathReturnsNullopt)
 
 TEST_P (EntityTest, SolidStrokeCoverageIsCorrect)
 
 TEST_P (EntityTest, BorderMaskBlurCoverageIsCorrect)
 
 TEST_P (EntityTest, DrawAtlasNoColor)
 
 TEST_P (EntityTest, DrawAtlasWithColorAdvanced)
 
 TEST_P (EntityTest, DrawAtlasWithColorSimple)
 
 TEST_P (EntityTest, DrawAtlasUsesProvidedCullRectForCoverage)
 
 TEST_P (EntityTest, DrawAtlasWithOpacity)
 
 TEST_P (EntityTest, DrawAtlasNoColorFullSize)
 
 TEST_P (EntityTest, SolidFillCoverageIsCorrect)
 
 TEST_P (EntityTest, SolidFillShouldRenderIsCorrect)
 
 TEST_P (EntityTest, DoesNotCullEntitiesByDefault)
 
 TEST_P (EntityTest, ClipContentsShouldRenderIsCorrect)
 
 TEST_P (EntityTest, ClipContentsGetClipCoverageIsCorrect)
 
 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, RuntimeEffectCanSuccessfullyRender)
 
 TEST_P (EntityTest, RuntimeEffectSetsRightSizeWhenUniformIsStruct)
 
 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, PointFieldGeometryDivisions)
 
 TEST_P (EntityTest, PointFieldGeometryCoverage)
 
 TEST_P (EntityTest, ColorFilterContentsWithLargeGeometry)
 
 TEST_P (EntityTest, TextContentsCeilsGlyphScaleToDecimal)
 
 TEST_P (EntityTest, AdvancedBlendCoverageHintIsNotResetByEntityPass)
 
 TEST_P (EntityTest, SpecializationConstantsAreAppliedToVariants)
 
 TEST_P (EntityTest, DecalSpecializationAppliedToMorphologyFilter)
 
 TEST_P (EntityTest, ContentContextOptionsHasReasonableHashFunctions)
 
 TEST_P (EntityTest, FillPathGeometryGetPositionBufferReturnsExpectedMode)
 
 TEST_P (EntityTest, FailOnValidationError)
 
 TEST_P (EntityTest, CanComputeGeometryForEmptyPathsWithoutCrashing)
 
 TEST_P (EntityTest, CanRenderEmptyPathsWithoutCrashing)
 
 TEST (EntityGeometryTest, RectGeometryCoversArea)
 
 TEST (EntityGeometryTest, FillPathGeometryCoversArea)
 
 TEST (EntityGeometryTest, FillPathGeometryCoversAreaNoInnerRect)
 
 TEST (EntityGeometryTest, LineGeometryCoverage)
 
 TEST (EntityGeometryTest, RoundRectGeometryCoversArea)
 
 TEST (EntityGeometryTest, StrokePathGeometryTransformOfLine)
 
 TEST (EntityGeometryTest, GeometryResultHasReasonableDefaults)
 
 TEST_P (RenderTargetCacheTest, CachesUsedTexturesAcrossFrames)
 
 TEST_P (RenderTargetCacheTest, DoesNotPersistFailedAllocations)
 
 TEST_P (RenderTargetCacheTest, CachedTextureGetsNewAttachmentConfig)
 
 TEST_P (RenderTargetCacheTest, CreateWithEmptySize)
 
 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, 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, ColorBlendReturnsExpectedResults)
 
 TEST (GeometryTest, BlendModeToString)
 
 TEST (GeometryTest, CanConvertBetweenDegressAndRadians)
 
 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 (MatrixTest, Multiply)
 
 TEST (PathTest, CubicPathComponentPolylineDoesNotIncludePointOne)
 
 TEST (PathTest, PathCreatePolyLineDoesNotDuplicatePoints)
 
 TEST (PathTest, PathBuilderSetsCorrectContourPropertiesForAddCommands)
 
 TEST (PathTest, PathCreatePolylineGeneratesCorrectContourData)
 
 TEST (PathTest, PolylineGetContourPointBoundsReturnsCorrectRanges)
 
 TEST (PathTest, PathAddRectPolylineHasCorrectContourData)
 
 TEST (PathTest, PathPolylineDuplicatesAreRemovedForSameContour)
 
 TEST (PathTest, PolylineBufferReuse)
 
 TEST (PathTest, PolylineFailsWithNullptrBuffer)
 
 TEST (PathTest, PathShifting)
 
 TEST (PathTest, PathBuilderWillComputeBounds)
 
 TEST (PathTest, PathHorizontalLine)
 
 TEST (PathTest, PathVerticalLine)
 
 TEST (PathTest, QuadradicPath)
 
 TEST (PathTest, CubicPath)
 
 TEST (PathTest, BoundingBoxCubic)
 
 TEST (PathTest, BoundingBoxOfCompositePathIsCorrect)
 
 TEST (PathTest, ExtremaOfCubicPathComponentIsCorrect)
 
 TEST (PathTest, PathGetBoundingBoxForCubicWithNoDerivativeRootsIsCorrect)
 
 TEST (PathTest, EmptyPath)
 
 TEST (PathTest, SimplePath)
 
 TEST (PathTest, CanBeCloned)
 
 TEST (PathTest, PathBuilderDoesNotMutateCopiedPaths)
 
 TEST (RectTest, RectEmptyDeclaration)
 
 TEST (RectTest, IRectEmptyDeclaration)
 
 TEST (RectTest, RectDefaultConstructor)
 
 TEST (RectTest, IRectDefaultConstructor)
 
 TEST (RectTest, RectSimpleLTRB)
 
 TEST (RectTest, IRectSimpleLTRB)
 
 TEST (RectTest, RectSimpleXYWH)
 
 TEST (RectTest, IRectSimpleXYWH)
 
 TEST (RectTest, RectOverflowXYWH)
 
 TEST (RectTest, IRectOverflowXYWH)
 
 TEST (RectTest, RectOverflowLTRB)
 
 TEST (RectTest, IRectOverflowLTRB)
 
 TEST (RectTest, RectMakeSize)
 
 TEST (RectTest, RectMakeMaximum)
 
 TEST (RectTest, IRectMakeMaximum)
 
 TEST (RectTest, RectFromRect)
 
 TEST (RectTest, IRectFromIRect)
 
 TEST (RectTest, RectCopy)
 
 TEST (RectTest, IRectCopy)
 
 TEST (RectTest, RectOriginSizeXYWHGetters)
 
 TEST (RectTest, IRectOriginSizeXYWHGetters)
 
 TEST (RectTest, RectRoundOutEmpty)
 
 TEST (RectTest, RectRoundOutSimple)
 
 TEST (RectTest, RectRoundOutToIRectHuge)
 
 TEST (RectTest, RectDoesNotIntersectEmpty)
 
 TEST (RectTest, IRectDoesNotIntersectEmpty)
 
 TEST (RectTest, EmptyRectDoesNotIntersect)
 
 TEST (RectTest, EmptyIRectDoesNotIntersect)
 
 TEST (RectTest, RectScale)
 
 TEST (RectTest, IRectScale)
 
 TEST (RectTest, RectArea)
 
 TEST (RectTest, IRectArea)
 
 TEST (RectTest, RectGetNormalizingTransform)
 
 TEST (RectTest, IRectGetNormalizingTransform)
 
 TEST (RectTest, RectXYWHIsEmpty)
 
 TEST (RectTest, IRectXYWHIsEmpty)
 
 TEST (RectTest, MakePointBoundsQuad)
 
 TEST (RectTest, IsSquare)
 
 TEST (RectTest, GetCenter)
 
 TEST (RectTest, RectExpand)
 
 TEST (RectTest, IRectExpand)
 
 TEST (RectTest, ContainsFloatingPoint)
 
template<typename R >
static constexpr R flip_lr (R rect)
 
template<typename R >
static constexpr R flip_tb (R rect)
 
template<typename R >
static constexpr R flip_lrtb (R rect)
 
static constexpr Rect swap_nan (const Rect &rect, int index)
 
static constexpr Point swap_nan (const Point &point, int index)
 
 TEST (RectTest, RectUnion)
 
 TEST (RectTest, OptRectUnion)
 
 TEST (RectTest, IRectUnion)
 
 TEST (RectTest, OptIRectUnion)
 
 TEST (RectTest, RectIntersection)
 
 TEST (RectTest, OptRectIntersection)
 
 TEST (RectTest, IRectIntersection)
 
 TEST (RectTest, OptIRectIntersection)
 
 TEST (RectTest, RectIntersectsWithRect)
 
 TEST (RectTest, IRectIntersectsWithRect)
 
 TEST (RectTest, RectContainsPoint)
 
 TEST (RectTest, IRectContainsIPoint)
 
 TEST (RectTest, RectContainsRect)
 
 TEST (RectTest, IRectContainsIRect)
 
 TEST (RectTest, RectCutOut)
 
 TEST (RectTest, IRectCutOut)
 
 TEST (RectTest, RectGetPoints)
 
 TEST (RectTest, RectShift)
 
 TEST (RectTest, RectGetTransformedPoints)
 
 TEST (RectTest, RectMakePointBounds)
 
 TEST (RectTest, RectGetPositive)
 
 TEST (RectTest, RectDirections)
 
 TEST (RectTest, RectProject)
 
 TEST (RectTest, RectRoundOut)
 
 TEST (RectTest, IRectRoundOut)
 
 TEST (SaturatedMath, ExplicitAddOfSignedInts)
 
 TEST (SaturatedMath, ImplicitAddOfSignedInts)
 
 TEST (SaturatedMath, ExplicitAddOfFloatingPoint)
 
 TEST (SaturatedMath, ImplicitAddOfFloatingPoint)
 
 TEST (SaturatedMath, ExplicitSubOfSignedInts)
 
 TEST (SaturatedMath, ImplicitSubOfSignedInts)
 
 TEST (SaturatedMath, ExplicitSubOfFloatingPoint)
 
 TEST (SaturatedMath, ImplicitSubOfFloatingPoint)
 
 TEST (SaturatedMath, ExplicitAverageScalarOfSignedInts)
 
 TEST (SaturatedMath, ImplicitAverageScalarOfSignedInts)
 
 TEST (SaturatedMath, ExplicitAverageScalarOfFloatingPoint)
 
 TEST (SaturatedMath, ImplicitAverageScalarOfFloatingPoint)
 
 TEST (SaturatedMath, CastingFiniteDoubleToFloatStaysFinite)
 
 TEST (SaturatedMath, CastingInfiniteDoubleToFloatStaysInfinite)
 
 TEST (SaturatedMath, CastingNaNDoubleToFloatStaysNaN)
 
 TEST (SaturatedMath, CastingLargeScalarToSignedIntProducesLimit)
 
 TEST (SaturatedMath, CastingInfiniteScalarToSignedIntProducesLimit)
 
 TEST (SaturatedMath, CastingNaNScalarToSignedIntProducesZero)
 
 TEST (SizeTest, SizeIsEmpty)
 
 TEST (SizeTest, ISizeIsEmpty)
 
 TEST (SizeTest, IsSquare)
 
 TEST (SizeTest, MaxDimension)
 
 TEST (SizeTest, NegationOperator)
 
 TEST (TrigTest, TrigAngles)
 
 TEST (TrigTest, MultiplyByScalarRadius)
 
 TEST_F (GoldenTests, ConicalGradient)
 
 TEST (TextureMTL, CreateFromDrawable)
 
 TEST (AllocatorVKTest, ToVKImageUsageFlags)
 
 TEST (AllocatorVKTest, MemoryTypeSelectionSingleHeap)
 
 TEST (AllocatorVKTest, MemoryTypeSelectionTwoHeap)
 
 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 (CommandPoolRecyclerVKTest, CommandBuffersAreRecycled)
 
 TEST (ContextVKTest, CommonHardwareConcurrencyConfigurations)
 
 TEST (ContextVKTest, DeletesCommandPools)
 
 TEST (ContextVKTest, DeletesCommandPoolsOnAllThreads)
 
 TEST (ContextVKTest, DeletePipelineAfterContext)
 
 TEST (ContextVKTest, DeleteShaderFunctionAfterContext)
 
 TEST (ContextVKTest, DeletePipelineLibraryAfterContext)
 
 TEST (ContextVKTest, CanCreateContextInAbsenceOfValidationLayers)
 
 TEST (ContextVKTest, CanCreateContextWithValidationLayers)
 
 TEST (CapabilitiesVKTest, ContextInitializesWithNoStencilFormat)
 
 TEST (CapabilitiesVKTest, ContextFailsInitializationForNoCombinedDepthStencilFormat)
 
 TEST (ContextVKTest, WarmUpFunctionCreatesRenderPass)
 
 TEST (DescriptorPoolRecyclerVKTest, GetDescriptorPoolRecyclerCreatesNewPools)
 
 TEST (DescriptorPoolRecyclerVKTest, ReclaimMakesDescriptorPoolAvailable)
 
 TEST (DescriptorPoolRecyclerVKTest, ReclaimDropsDescriptorPoolIfSizeIsExceeded)
 
 INSTANTIATE_VULKAN_PLAYGROUND_SUITE (DriverInfoVKTest)
 
 TEST_P (DriverInfoVKTest, CanQueryDriverInfo)
 
 TEST (FenceWaiterVKTest, IgnoresNullFence)
 
 TEST (FenceWaiterVKTest, IgnoresNullCallback)
 
 TEST (FenceWaiterVKTest, ExecutesFenceCallback)
 
 TEST (FenceWaiterVKTest, ExecutesFenceCallbackX2)
 
 TEST (FenceWaiterVKTest, ExecutesNewFenceThenOldFence)
 
 TEST (FenceWaiterVKTest, AddFenceDoesNothingIfTerminating)
 
 TEST (FenceWaiterVKTest, InProgressFencesStillWaitIfTerminated)
 
 TEST (RenderPassBuilder, CreatesRenderPassWithNoDepthStencil)
 
 TEST (RenderPassBuilder, CreatesRenderPassWithCombinedDepthStencil)
 
 TEST (RenderPassBuilder, CreatesRenderPassWithOnlyStencil)
 
 TEST (RenderPassBuilder, CreatesMSAAResolveWithCorrectStore)
 
 TEST_P (RendererTest, CachesRenderPassAndFramebuffer)
 
 TEST (ResourceManagerVKTest, CreatesANewInstance)
 
 TEST (ResourceManagerVKTest, ReclaimMovesAResourceAndDestroysIt)
 
 TEST (ResourceManagerVKTest, TerminatesWhenOutOfScope)
 
 TEST (ResourceManagerVKTest, IsThreadSafe)
 
 INSTANTIATE_PLAYGROUND_SUITE (BlitPassTest)
 
 TEST_P (BlitPassTest, BlitAcrossDifferentPixelFormatsFails)
 
 TEST_P (BlitPassTest, BlitAcrossDifferentSampleCountsFails)
 
 TEST_P (BlitPassTest, BlitPassesForMatchingFormats)
 
 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 (SupportsReadFromResolve, false)
 
 CAPABILITY_TEST (SupportsDecalSamplerAddressMode, false)
 
 CAPABILITY_TEST (SupportsDeviceTransientTextures, false)
 
 TEST (CapabilitiesTest, DefaultColorFormat)
 
 TEST (CapabilitiesTest, DefaultStencilFormat)
 
 TEST (CapabilitiesTest, DefaultDepthStencilFormat)
 
 TEST (CapabilitiesTest, DefaultGlyphAtlasFormat)
 
 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 (PipelineDescriptorTest, PrimitiveTypeHashEquality)
 
 TEST (PoolTest, Simple)
 
 TEST (PoolTest, Overload)
 
static void InstantiateTestShaderLibrary (Context::BackendType backend_type)
 
 INSTANTIATE_PLAYGROUND_SUITE (RendererDartTest)
 
 TEST_P (RendererDartTest, CanRunDartInPlaygroundFrame)
 
 TEST_P (RendererDartTest, CanInstantiateFlutterGPUContext)
 
 DART_TEST_CASE (canCreateShaderLibrary)
 
 DART_TEST_CASE (canReflectUniformStructs)
 
 DART_TEST_CASE (uniformBindFailsForInvalidHostBufferOffset)
 
 DART_TEST_CASE (canCreateRenderPassAndSubmit)
 
 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)
 
 TEST_P (RendererTest, CanLookupRenderTargetProperties)
 
 TEST_P (RendererTest, RenderTargetCreateOffscreenMSAASetsDefaultDepthStencilFormat)
 
template<class VertexShader , class FragmentShader >
std::shared_ptr< Pipeline< PipelineDescriptor > > CreateDefaultPipeline (const std::shared_ptr< Context > &context)
 
 TEST_P (RendererTest, CanSepiaToneWithSubpasses)
 
 TEST_P (RendererTest, CanSepiaToneThenSwizzleWithSubpasses)
 
 INSTANTIATE_PLAYGROUND_SUITE (RuntimeStageTest)
 
 TEST_P (RuntimeStageTest, CanReadValidBlob)
 
 TEST_P (RuntimeStageTest, CanRejectInvalidBlob)
 
 TEST_P (RuntimeStageTest, CanReadUniforms)
 
 TEST_P (RuntimeStageTest, CanRegisterStage)
 
 TEST_P (RuntimeStageTest, CanCreatePipelineFromRuntimeStage)
 
 TEST_P (RuntimeStageTest, ContainsExpectedShaderTypes)
 
static std::shared_ptr< fml::Mapping > CreateMappingFromString (std::string p_string)
 
const std::string CreateStringFromMapping (const fml::Mapping &mapping)
 
 TEST (ShaderArchiveTest, CanReadAndWriteBlobs)
 
 TEST (ShaderArchiveTest, ArchiveAndMultiArchiveHaveDifferentIdentifiers)
 
 TEST (TessellatorTest, TessellatorBuilderReturnsCorrectResultStatus)
 
 TEST (TessellatorTest, TessellateConvex)
 
 TEST (TessellatorTest, CircleVertexCounts)
 
 TEST (TessellatorTest, FilledCircleTessellationVertices)
 
 TEST (TessellatorTest, StrokedCircleTessellationVertices)
 
 TEST (TessellatorTest, RoundCapLineTessellationVertices)
 
 TEST (TessellatorTest, FilledEllipseTessellationVertices)
 
 TEST (TessellatorTest, FilledRoundRectTessellationVertices)
 
 TEST (TessellatorTest, EarlyReturnEmptyConvexShape)
 
 TEST (TessellatorTest, ChecksConcurrentPolylineUsage)
 
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)
 
 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)
 
 TEST_P (TypographerTest, GlyphAtlasTextureIsRecycledWhenContentsAreNotRecreated)
 

Variables

static const std::map< std::string, MaskBlurTestConfigkPaintVariations
 
static constexpr std::string_view kFontFixture
 
std::vector< Pointgolden_cubic_and_quad_points
 

Typedef Documentation

◆ AiksCanvasTest

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

Definition at line 16 of file canvas_unittests.cc.

◆ AiksTest

Definition at line 17 of file aiks_unittests.h.

◆ BlitPassTest

Definition at line 15 of file blit_pass_unittests.cc.

◆ ComputeSubgroupTest

◆ ComputeTest

Definition at line 21 of file compute_unittests.cc.

◆ DeviceBufferTest

Definition at line 12 of file device_buffer_unittests.cc.

◆ DisplayListTest

Definition at line 46 of file dl_unittests.cc.

◆ DriverInfoVKTest

◆ EntityPassTargetTest

◆ EntityTest

◆ HostBufferTest

◆ RendererTest

◆ RenderTargetCacheTest

◆ 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 ( Vector2  content_scale,
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 (bottom images).

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

Definition at line 2233 of file aiks_unittests.cc.

2236  {
2237  Color destination_color = Color::CornflowerBlue().WithAlpha(0.75);
2238  auto source_colors = std::vector<Color>({Color::White().WithAlpha(0.75),
2239  Color::LimeGreen().WithAlpha(0.75),
2240  Color::Black().WithAlpha(0.75)});
2241 
2242  Canvas canvas;
2243  canvas.DrawPaint({.color = Color::Black()});
2244  // TODO(bdero): Why does this cause the left image to double scale on high DPI
2245  // displays.
2246  // canvas.Scale(content_scale);
2247 
2248  //----------------------------------------------------------------------------
2249  /// 1. Save layer blending (top squares).
2250  ///
2251 
2252  canvas.Save();
2253  for (const auto& color : source_colors) {
2254  canvas.Save();
2255  {
2256  canvas.ClipRect(Rect::MakeXYWH(25, 25, 100, 100));
2257  // Perform the blend in a SaveLayer so that the initial backdrop color is
2258  // fully transparent black. SourceOver blend the result onto the parent
2259  // pass.
2260  canvas.SaveLayer({});
2261  {
2262  canvas.DrawPaint({.color = destination_color});
2263  // Draw the source color in an offscreen pass and blend it to the parent
2264  // pass.
2265  canvas.SaveLayer({.blend_mode = blend_mode});
2266  { //
2267  canvas.DrawRect(Rect::MakeXYWH(25, 25, 100, 100), {.color = color});
2268  }
2269  canvas.Restore();
2270  }
2271  canvas.Restore();
2272  }
2273  canvas.Restore();
2274  canvas.Translate(Vector2(100, 0));
2275  }
2276  canvas.RestoreToCount(0);
2277 
2278  //----------------------------------------------------------------------------
2279  /// 2. CPU blend modes (bottom squares).
2280  ///
2281 
2282  canvas.Save();
2283  canvas.Translate({0, 100});
2284  // Perform the blend in a SaveLayer so that the initial backdrop color is
2285  // fully transparent black. SourceOver blend the result onto the parent pass.
2286  canvas.SaveLayer({});
2287  for (const auto& color : source_colors) {
2288  // Simply write the CPU blended color to the pass.
2289  canvas.DrawRect(Rect::MakeXYWH(25, 25, 100, 100),
2290  {.color = destination_color.Blend(color, blend_mode),
2291  .blend_mode = BlendMode::kSourceOver});
2292  canvas.Translate(Vector2(100, 0));
2293  }
2294  canvas.Restore();
2295  canvas.Restore();
2296 
2297  //----------------------------------------------------------------------------
2298  /// 3. Image blending (bottom images).
2299  ///
2300  /// Compare these results with the images in the Flutter blend mode
2301  /// documentation: https://api.flutter.dev/flutter/dart-ui/BlendMode.html
2302  ///
2303 
2304  canvas.Translate({0, 250});
2305 
2306  // Draw grid behind the images.
2307  canvas.DrawRect(Rect::MakeLTRB(0, 0, 800, 400),
2308  {.color = Color::MakeRGBA8(41, 41, 41, 255)});
2309  Paint square_paint = {.color = Color::MakeRGBA8(15, 15, 15, 255)};
2310  for (int y = 0; y < 400 / 8; y++) {
2311  for (int x = 0; x < 800 / 16; x++) {
2312  canvas.DrawRect(Rect::MakeXYWH(x * 16 + (y % 2) * 8, y * 8, 8, 8),
2313  square_paint);
2314  }
2315  }
2316 
2317  // Uploaded image source (left image).
2318  canvas.Save();
2319  canvas.SaveLayer({.blend_mode = BlendMode::kSourceOver});
2320  {
2321  canvas.DrawImage(dst_image, {0, 0}, {.blend_mode = BlendMode::kSourceOver});
2322  canvas.DrawImage(src_image, {0, 0}, {.blend_mode = blend_mode});
2323  }
2324  canvas.Restore();
2325  canvas.Restore();
2326 
2327  // Rendered image source (right image).
2328  canvas.Save();
2329  canvas.SaveLayer({.blend_mode = BlendMode::kSourceOver});
2330  {
2331  canvas.DrawImage(dst_image, {400, 0},
2332  {.blend_mode = BlendMode::kSourceOver});
2333  canvas.SaveLayer({.blend_mode = blend_mode});
2334  {
2335  canvas.DrawImage(src_image, {400, 0},
2336  {.blend_mode = BlendMode::kSourceOver});
2337  }
2338  canvas.Restore();
2339  }
2340  canvas.Restore();
2341  canvas.Restore();
2342 
2343  return canvas.EndRecordingAsPicture();
2344 }

References impeller::Color::Black(), impeller::Color::Blend(), impeller::Paint::color, impeller::Color::CornflowerBlue(), impeller::Canvas::DrawPaint(), impeller::kSourceOver, impeller::Color::LimeGreen(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Color::MakeRGBA8(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Color::White(), and impeller::Color::WithAlpha().

◆ CanRenderConicalGradientWithDithering()

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

Definition at line 166 of file aiks_gradient_unittests.cc.

167  {
168  Canvas canvas;
169  canvas.Scale(aiks_test->GetContentScale());
170  Paint paint;
171  canvas.Translate({100.0, 100.0, 0});
172 
173  // #FFF -> #000
174  std::vector<Color> colors = {Color{1.0, 1.0, 1.0, 1.0},
175  Color{0.0, 0.0, 0.0, 1.0}};
176  std::vector<Scalar> stops = {0.0, 1.0};
177 
178  paint.color_source = ColorSource::MakeConicalGradient(
179  {100, 100}, 100, std::move(colors), std::move(stops), {0, 1}, 0,
180  Entity::TileMode::kMirror, {});
181  paint.dither = use_dithering;
182 
183  canvas.DrawRect(Rect::MakeXYWH(0, 0, 600, 600), paint);
184  ASSERT_TRUE(aiks_test->OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
185 }

References impeller::Paint::color_source, impeller::Paint::dither, impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Playground::GetContentScale(), impeller::Entity::kMirror, impeller::ColorSource::MakeConicalGradient(), impeller::TRect< Scalar >::MakeXYWH(), 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 82 of file aiks_gradient_unittests.cc.

83  {
84  Canvas canvas;
85  Paint paint;
86  canvas.Translate({100.0, 100.0, 0});
87 
88  // 0xffcccccc --> 0xff333333, taken from
89  // https://github.com/flutter/flutter/issues/118073#issue-1521699748
90  std::vector<Color> colors = {Color{0.8, 0.8, 0.8, 1.0},
91  Color{0.2, 0.2, 0.2, 1.0}};
92  std::vector<Scalar> stops = {0.0, 1.0};
93 
94  paint.color_source = ColorSource::MakeLinearGradient(
95  {0, 0}, {800, 500}, std::move(colors), std::move(stops),
96  Entity::TileMode::kClamp, {});
97  paint.dither = use_dithering;
98  canvas.DrawRect(Rect::MakeXYWH(0, 0, 800, 500), paint);
99  ASSERT_TRUE(aiks_test->OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
100 }

References impeller::Paint::color_source, impeller::Paint::dither, impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kClamp, impeller::ColorSource::MakeLinearGradient(), impeller::TRect< Scalar >::MakeXYWH(), 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 110 of file aiks_gradient_unittests.cc.

111  {
112  Canvas canvas;
113  Paint paint;
114  canvas.Translate({100.0, 100.0, 0});
115 
116  // #FFF -> #000
117  std::vector<Color> colors = {Color{1.0, 1.0, 1.0, 1.0},
118  Color{0.0, 0.0, 0.0, 1.0}};
119  std::vector<Scalar> stops = {0.0, 1.0};
120 
121  paint.color_source = ColorSource::MakeRadialGradient(
122  {600, 600}, 600, std::move(colors), std::move(stops),
123  Entity::TileMode::kClamp, {});
124  paint.dither = use_dithering;
125  canvas.DrawRect(Rect::MakeXYWH(0, 0, 1200, 1200), paint);
126  ASSERT_TRUE(aiks_test->OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
127 }

References impeller::Paint::color_source, impeller::Paint::dither, impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kClamp, impeller::ColorSource::MakeRadialGradient(), impeller::TRect< Scalar >::MakeXYWH(), 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 137 of file aiks_gradient_unittests.cc.

138  {
139  Canvas canvas;
140  canvas.Scale(aiks_test->GetContentScale());
141  Paint paint;
142  canvas.Translate({100.0, 100.0, 0});
143 
144  // #FFF -> #000
145  std::vector<Color> colors = {Color{1.0, 1.0, 1.0, 1.0},
146  Color{0.0, 0.0, 0.0, 1.0}};
147  std::vector<Scalar> stops = {0.0, 1.0};
148 
149  paint.color_source = ColorSource::MakeSweepGradient(
150  {100, 100}, Degrees(45), Degrees(135), std::move(colors),
151  std::move(stops), Entity::TileMode::kMirror, {});
152  paint.dither = use_dithering;
153 
154  canvas.DrawRect(Rect::MakeXYWH(0, 0, 600, 600), paint);
155  ASSERT_TRUE(aiks_test->OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
156 }

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

Referenced by TEST_P().

◆ CAPABILITY_TEST() [1/10]

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

◆ CAPABILITY_TEST() [2/10]

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

◆ CAPABILITY_TEST() [3/10]

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

◆ CAPABILITY_TEST() [4/10]

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

◆ CAPABILITY_TEST() [5/10]

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

◆ CAPABILITY_TEST() [6/10]

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

◆ CAPABILITY_TEST() [7/10]

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

◆ CAPABILITY_TEST() [8/10]

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

◆ CAPABILITY_TEST() [9/10]

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

◆ CAPABILITY_TEST() [10/10]

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

◆ CompareFunctionUI()

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

Definition at line 1111 of file renderer_unittests.cc.

1111  {
1112  static CompareFunctionUIData data;
1113  return data;
1114 }

Referenced by TEST_P().

◆ CreateColorVertices()

std::shared_ptr<VerticesGeometry> impeller::testing::CreateColorVertices ( const std::vector< Point > &  vertices,
const std::vector< Color > &  colors 
)

Definition at line 26 of file vertices_contents_unittests.cc.

28  {
29  auto bounds = Rect::MakePointBounds(vertices.begin(), vertices.end());
30  std::vector<uint16_t> indices = {};
31  indices.reserve(vertices.size());
32  for (auto i = 0u; i < vertices.size(); i++) {
33  indices.emplace_back(i);
34  }
35  std::vector<Point> texture_coordinates = {};
36 
37  return std::make_shared<VerticesGeometry>(
38  vertices, indices, texture_coordinates, colors,
39  bounds.value_or(Rect::MakeLTRB(0, 0, 0, 0)),
40  VerticesGeometry::VertexMode::kTriangles);
41 }

References impeller::VerticesGeometry::kTriangles, impeller::TRect< Scalar >::MakeLTRB(), and impeller::TRect< Scalar >::MakePointBounds().

Referenced by TEST_P().

◆ CreateDefaultPipeline()

template<class VertexShader , class FragmentShader >
std::shared_ptr<Pipeline<PipelineDescriptor> > impeller::testing::CreateDefaultPipeline ( const std::shared_ptr< Context > &  context)

Definition at line 1303 of file renderer_unittests.cc.

1304  {
1305  using TexturePipelineBuilder = PipelineBuilder<VertexShader, FragmentShader>;
1306  auto pipeline_desc =
1307  TexturePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
1308  if (!pipeline_desc.has_value()) {
1309  return nullptr;
1310  }
1311  pipeline_desc->SetSampleCount(SampleCount::kCount4);
1312  pipeline_desc->SetStencilAttachmentDescriptors(std::nullopt);
1313  auto pipeline =
1314  context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
1315  if (!pipeline || !pipeline->IsValid()) {
1316  return nullptr;
1317  }
1318  return pipeline;
1319 }

References impeller::kCount4.

◆ 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 28 of file typographer_unittests.cc.

34  {
35  FontGlyphMap font_glyph_map;
36  frame.CollectUniqueFontGlyphPairs(font_glyph_map, scale);
37  return typographer_context->CreateGlyphAtlas(context, type, atlas_context,
38  font_glyph_map);
39 }

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

Referenced by TEST_P().

◆ CreateMappingFromString()

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

Definition at line 20 of file shader_archive_unittests.cc.

21  {
22  auto string = std::make_shared<std::string>(std::move(p_string));
23  return std::make_shared<fml::NonOwnedMapping>(
24  reinterpret_cast<const uint8_t*>(string->data()), string->size(),
25  [string](auto, auto) {});
26 }

Referenced by TEST().

◆ CreatePassWithRectPath()

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

Definition at line 109 of file entity_unittests.cc.

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

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 28 of file shader_archive_unittests.cc.

28  {
29  return std::string{reinterpret_cast<const char*>(mapping.GetMapping()),
30  mapping.GetSize()};
31 }

Referenced by TEST().

◆ CreateTestYUVTextures()

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

Definition at line 2110 of file entity_unittests.cc.

2112  {
2113  Vector3 red = {244.0 / 255.0, 67.0 / 255.0, 54.0 / 255.0};
2114  Vector3 green = {76.0 / 255.0, 175.0 / 255.0, 80.0 / 255.0};
2115  Vector3 blue = {33.0 / 255.0, 150.0 / 255.0, 243.0 / 255.0};
2116  Vector3 white = {1.0, 1.0, 1.0};
2117  Vector3 red_yuv = RGBToYUV(red, yuv_color_space);
2118  Vector3 green_yuv = RGBToYUV(green, yuv_color_space);
2119  Vector3 blue_yuv = RGBToYUV(blue, yuv_color_space);
2120  Vector3 white_yuv = RGBToYUV(white, yuv_color_space);
2121  std::vector<Vector3> yuvs{red_yuv, green_yuv, blue_yuv, white_yuv};
2122  std::vector<uint8_t> y_data;
2123  std::vector<uint8_t> uv_data;
2124  for (int i = 0; i < 4; i++) {
2125  auto yuv = yuvs[i];
2126  uint8_t y = std::round(yuv.x * 255.0);
2127  uint8_t u = std::round(yuv.y * 255.0);
2128  uint8_t v = std::round(yuv.z * 255.0);
2129  for (int j = 0; j < 16; j++) {
2130  y_data.push_back(y);
2131  }
2132  for (int j = 0; j < 8; j++) {
2133  uv_data.push_back(j % 2 == 0 ? u : v);
2134  }
2135  }
2136  impeller::TextureDescriptor y_texture_descriptor;
2137  y_texture_descriptor.storage_mode = impeller::StorageMode::kHostVisible;
2138  y_texture_descriptor.format = PixelFormat::kR8UNormInt;
2139  y_texture_descriptor.size = {8, 8};
2140  auto y_texture =
2141  context->GetResourceAllocator()->CreateTexture(y_texture_descriptor);
2142  auto y_mapping = std::make_shared<fml::DataMapping>(y_data);
2143  if (!y_texture->SetContents(y_mapping)) {
2144  FML_DLOG(ERROR) << "Could not copy contents into Y texture.";
2145  }
2146 
2147  impeller::TextureDescriptor uv_texture_descriptor;
2148  uv_texture_descriptor.storage_mode = impeller::StorageMode::kHostVisible;
2149  uv_texture_descriptor.format = PixelFormat::kR8G8UNormInt;
2150  uv_texture_descriptor.size = {4, 4};
2151  auto uv_texture =
2152  context->GetResourceAllocator()->CreateTexture(uv_texture_descriptor);
2153  auto uv_mapping = std::make_shared<fml::DataMapping>(uv_data);
2154  if (!uv_texture->SetContents(uv_mapping)) {
2155  FML_DLOG(ERROR) << "Could not copy contents into UV texture.";
2156  }
2157 
2158  return {y_texture, uv_texture};
2159 }

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().

◆ DART_TEST_CASE() [1/4]

impeller::testing::DART_TEST_CASE ( canCreateRenderPassAndSubmit  )

◆ DART_TEST_CASE() [2/4]

impeller::testing::DART_TEST_CASE ( canCreateShaderLibrary  )

These test entries correspond to Dart functions located in flutter/impeller/fixtures/dart_tests.dart

◆ DART_TEST_CASE() [3/4]

impeller::testing::DART_TEST_CASE ( canReflectUniformStructs  )

◆ DART_TEST_CASE() [4/4]

impeller::testing::DART_TEST_CASE ( uniformBindFailsForInvalidHostBufferOffset  )

◆ flip_lr()

template<typename R >
static constexpr R impeller::testing::flip_lr ( rect)
inlinestaticconstexpr

Definition at line 1279 of file rect_unittests.cc.

1279  {
1280  return R::MakeLTRB(rect.GetRight(), rect.GetTop(), //
1281  rect.GetLeft(), rect.GetBottom());
1282 }

Referenced by flip_lrtb(), and TEST().

◆ flip_lrtb()

template<typename R >
static constexpr R impeller::testing::flip_lrtb ( rect)
inlinestaticconstexpr

Definition at line 1291 of file rect_unittests.cc.

1291  {
1292  return flip_lr(flip_tb(rect));
1293 }

References flip_lr(), and flip_tb().

Referenced by TEST().

◆ flip_tb()

template<typename R >
static constexpr R impeller::testing::flip_tb ( rect)
inlinestaticconstexpr

Definition at line 1285 of file rect_unittests.cc.

1285  {
1286  return R::MakeLTRB(rect.GetLeft(), rect.GetBottom(), //
1287  rect.GetRight(), rect.GetTop());
1288 }

Referenced by flip_lrtb(), and TEST().

◆ GetBlendModeSelection()

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

Definition at line 1040 of file aiks_unittests.cc.

1040  {
1041  std::vector<const char*> blend_mode_names;
1042  std::vector<BlendMode> blend_mode_values;
1043  {
1044  const std::vector<std::tuple<const char*, BlendMode>> blends = {
1046  assert(blends.size() ==
1047  static_cast<size_t>(Entity::kLastAdvancedBlendMode) + 1);
1048  for (const auto& [name, mode] : blends) {
1049  blend_mode_names.push_back(name);
1050  blend_mode_values.push_back(mode);
1051  }
1052  }
1053 
1054  return {blend_mode_names, blend_mode_values};
1055 }

References BLEND_MODE_TUPLE, IMPELLER_FOR_EACH_BLEND_MODE, and impeller::Entity::kLastAdvancedBlendMode.

Referenced by TEST_P().

◆ GetCoverageOfFirstEntity()

template<typename Contents >
static std::optional<Rect> impeller::testing::GetCoverageOfFirstEntity ( const Picture picture)
static

Definition at line 1752 of file dl_unittests.cc.

1752  {
1753  std::optional<Rect> coverage;
1754  picture.pass->IterateAllEntities([&coverage](Entity& entity) {
1755  if (std::static_pointer_cast<Contents>(entity.GetContents())) {
1756  auto contents = std::static_pointer_cast<Contents>(entity.GetContents());
1757  Entity entity;
1758  coverage = contents->GetCoverage(entity);
1759  return false;
1760  }
1761  return true;
1762  });
1763  return coverage;
1764 }

References impeller::Entity::GetContents(), and impeller::Picture::pass.

◆ INSTANTIATE_COMPUTE_SUITE()

impeller::testing::INSTANTIATE_COMPUTE_SUITE ( ComputeSubgroupTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [1/7]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( AiksTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [2/7]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( BlitPassTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [3/7]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( DisplayListTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [4/7]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( GaussianBlurFilterContentsTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [5/7]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( HostBufferTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [6/7]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( RendererDartTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [7/7]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( RuntimeStageTest  )

◆ INSTANTIATE_VULKAN_PLAYGROUND_SUITE()

impeller::testing::INSTANTIATE_VULKAN_PLAYGROUND_SUITE ( DriverInfoVKTest  )

◆ InstantiateTestShaderLibrary()

static void impeller::testing::InstantiateTestShaderLibrary ( Context::BackendType  backend_type)
static

Definition at line 28 of file renderer_dart_unittests.cc.

28  {
29  auto fixture =
30  flutter::testing::OpenFixtureAsMapping("playground.shaderbundle");
31  auto library = flutter::gpu::ShaderLibrary::MakeFromFlatbuffer(
32  backend_type, std::move(fixture));
33  flutter::gpu::ShaderLibrary::SetOverride(library);
34 }

Referenced by impeller::testing::RendererDartTest::GetIsolate().

◆ MaskBlurVariantTest()

static Picture impeller::testing::MaskBlurVariantTest ( const AiksTest test_context,
const MaskBlurTestConfig config 
)
static

Definition at line 294 of file aiks_blur_unittests.cc.

295  {
296  Canvas canvas;
297  canvas.Scale(test_context.GetContentScale());
298  canvas.Scale(Vector2{0.8f, 0.8f});
299  Paint paint;
300  paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
301  .style = FilterContents::BlurStyle::kNormal,
302  .sigma = Sigma{1},
303  };
304 
305  canvas.DrawPaint({.color = Color::AntiqueWhite()});
306 
307  paint.mask_blur_descriptor->style = config.style;
308  paint.mask_blur_descriptor->sigma = Sigma{config.sigma};
309  paint.image_filter = config.image_filter;
310  paint.invert_colors = config.invert_colors;
311  paint.blend_mode = config.blend_mode;
312 
313  const Scalar x = 50;
314  const Scalar radius = 20.0f;
315  const Scalar y_spacing = 100.0f;
316 
317  Scalar y = 50;
318  paint.color = Color::Crimson().WithAlpha(config.alpha);
319  canvas.DrawRect(Rect::MakeXYWH(x + 25 - radius / 2, y + radius / 2, //
320  radius, 60.0f - radius),
321  paint);
322 
323  y += y_spacing;
324  paint.color = Color::Blue().WithAlpha(config.alpha);
325  canvas.DrawCircle({x + 25, y + 25}, radius, paint);
326 
327  y += y_spacing;
328  paint.color = Color::Green().WithAlpha(config.alpha);
329  canvas.DrawOval(Rect::MakeXYWH(x + 25 - radius / 2, y + radius / 2, //
330  radius, 60.0f - radius),
331  paint);
332 
333  y += y_spacing;
334  paint.color = Color::Purple().WithAlpha(config.alpha);
335  canvas.DrawRRect(Rect::MakeXYWH(x, y, 60.0f, 60.0f), //
336  {radius, radius}, //
337  paint);
338 
339  y += y_spacing;
340  paint.color = Color::Orange().WithAlpha(config.alpha);
341  canvas.DrawRRect(Rect::MakeXYWH(x, y, 60.0f, 60.0f), //
342  {radius, 5.0f}, paint);
343 
344  y += y_spacing;
345  paint.color = Color::Maroon().WithAlpha(config.alpha);
346  canvas.DrawPath(PathBuilder{}
347  .MoveTo({x + 0, y + 60})
348  .LineTo({x + 30, y + 0})
349  .LineTo({x + 60, y + 60})
350  .Close()
351  .TakePath(),
352  paint);
353 
354  y += y_spacing;
355  paint.color = Color::Maroon().WithAlpha(config.alpha);
356  canvas.DrawPath(PathBuilder{}
357  .AddArc(Rect::MakeXYWH(x + 5, y, 50, 50),
358  Radians{kPi / 2}, Radians{kPi})
359  .AddArc(Rect::MakeXYWH(x + 25, y, 50, 50),
360  Radians{kPi / 2}, Radians{kPi})
361  .Close()
362  .TakePath(),
363  paint);
364 
365  return canvas.EndRecordingAsPicture();
366 }

References impeller::PathBuilder::AddArc(), impeller::testing::MaskBlurTestConfig::alpha, impeller::Color::AntiqueWhite(), impeller::Paint::blend_mode, impeller::testing::MaskBlurTestConfig::blend_mode, impeller::Color::Blue(), impeller::Close(), impeller::Paint::color, impeller::Color::Crimson(), impeller::Canvas::DrawCircle(), impeller::Canvas::DrawOval(), impeller::Canvas::DrawPaint(), impeller::Canvas::DrawPath(), impeller::Canvas::DrawRect(), impeller::Canvas::DrawRRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Playground::GetContentScale(), impeller::Color::Green(), impeller::Paint::image_filter, impeller::testing::MaskBlurTestConfig::image_filter, impeller::Paint::invert_colors, impeller::testing::MaskBlurTestConfig::invert_colors, impeller::FilterContents::kNormal, impeller::kPi, impeller::LineTo(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Color::Maroon(), impeller::Paint::mask_blur_descriptor, impeller::PathBuilder::MoveTo(), impeller::Color::Orange(), impeller::Color::Purple(), impeller::Canvas::Scale(), impeller::testing::MaskBlurTestConfig::sigma, impeller::Paint::MaskBlurDescriptor::style, impeller::testing::MaskBlurTestConfig::style, and impeller::Color::WithAlpha().

◆ RenderTextInCanvasSkia()

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

Definition at line 714 of file aiks_unittests.cc.

718  {}) {
719  // Draw the baseline.
720  canvas.DrawRect(
721  Rect::MakeXYWH(options.position.x - 50, options.position.y, 900, 10),
722  Paint{.color = Color::Aqua().WithAlpha(0.25)});
723 
724  // Mark the point at which the text is drawn.
725  canvas.DrawCircle(options.position, 5.0,
726  Paint{.color = Color::Red().WithAlpha(0.25)});
727 
728  // Construct the text blob.
729  auto c_font_fixture = std::string(font_fixture);
730  auto mapping = flutter::testing::OpenFixtureAsSkData(c_font_fixture.c_str());
731  if (!mapping) {
732  return false;
733  }
734  sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
735  SkFont sk_font(font_mgr->makeFromData(mapping), options.font_size);
736  auto blob = SkTextBlob::MakeFromString(text.c_str(), sk_font);
737  if (!blob) {
738  return false;
739  }
740 
741  // Create the Impeller text frame and draw it at the designated baseline.
742  auto frame = MakeTextFrameFromTextBlobSkia(blob);
743 
744  Paint text_paint;
745  text_paint.color = options.color;
746  text_paint.mask_blur_descriptor = options.mask_blur_descriptor;
747  canvas.DrawTextFrame(frame, options.position, text_paint);
748  return true;
749 }

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

755  {}) {
756  // Draw the baseline.
757  canvas.DrawRect(
758  Rect::MakeXYWH(options.position.x - 50, options.position.y, 900, 10),
759  Paint{.color = Color::Aqua().WithAlpha(0.25)});
760 
761  // Mark the point at which the text is drawn.
762  canvas.DrawCircle(options.position, 5.0,
763  Paint{.color = Color::Red().WithAlpha(0.25)});
764 
765  // Construct the text blob.
766  auto mapping = flutter::testing::OpenFixtureAsMapping(font_fixture.c_str());
767  if (!mapping) {
768  return false;
769  }
770  auto typeface_stb = std::make_shared<TypefaceSTB>(std::move(mapping));
771 
772  auto frame = MakeTextFrameSTB(
773  typeface_stb, Font::Metrics{.point_size = options.font_size}, text);
774 
775  Paint text_paint;
776  text_paint.color = options.color;
777  canvas.DrawTextFrame(frame, options.position, text_paint);
778  return true;
779 }

Referenced by TEST_P().

◆ RGBToYUV()

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

Definition at line 2093 of file entity_unittests.cc.

2093  {
2094  Vector3 yuv;
2095  switch (yuv_color_space) {
2096  case YUVColorSpace::kBT601FullRange:
2097  yuv.x = rgb.x * 0.299 + rgb.y * 0.587 + rgb.z * 0.114;
2098  yuv.y = rgb.x * -0.169 + rgb.y * -0.331 + rgb.z * 0.5 + 0.5;
2099  yuv.z = rgb.x * 0.5 + rgb.y * -0.419 + rgb.z * -0.081 + 0.5;
2100  break;
2101  case YUVColorSpace::kBT601LimitedRange:
2102  yuv.x = rgb.x * 0.257 + rgb.y * 0.516 + rgb.z * 0.100 + 0.063;
2103  yuv.y = rgb.x * -0.145 + rgb.y * -0.291 + rgb.z * 0.439 + 0.5;
2104  yuv.z = rgb.x * 0.429 + rgb.y * -0.368 + rgb.z * -0.071 + 0.5;
2105  break;
2106  }
2107  return yuv;
2108 }

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

Referenced by CreateTestYUVTextures().

◆ swap_nan() [1/2]

static constexpr Point impeller::testing::swap_nan ( const Point point,
int  index 
)
inlinestaticconstexpr

Definition at line 1305 of file rect_unittests.cc.

1305  {
1306  Scalar nan = std::numeric_limits<Scalar>::quiet_NaN();
1307  FML_DCHECK(index >= 0 && index <= 3);
1308  Scalar x = ((index & (1 << 0)) != 0) ? nan : point.x;
1309  Scalar y = ((index & (1 << 1)) != 0) ? nan : point.y;
1310  return Point(x, y);
1311 }

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

◆ swap_nan() [2/2]

static constexpr Rect impeller::testing::swap_nan ( const Rect rect,
int  index 
)
inlinestaticconstexpr

Definition at line 1295 of file rect_unittests.cc.

1295  {
1296  Scalar nan = std::numeric_limits<Scalar>::quiet_NaN();
1297  FML_DCHECK(index >= 0 && index <= 15);
1298  Scalar l = ((index & (1 << 0)) != 0) ? nan : rect.GetLeft();
1299  Scalar t = ((index & (1 << 1)) != 0) ? nan : rect.GetTop();
1300  Scalar r = ((index & (1 << 2)) != 0) ? nan : rect.GetRight();
1301  Scalar b = ((index & (1 << 3)) != 0) ? nan : rect.GetBottom();
1302  return Rect::MakeLTRB(l, t, r, b);
1303 }

References impeller::saturated::b, impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetTop(), and impeller::TRect< Scalar >::MakeLTRB().

Referenced by TEST().

◆ TEST() [1/370]

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

Definition at line 340 of file canvas_unittests.cc.

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

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

◆ TEST() [2/370]

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

Definition at line 18 of file canvas_unittests.cc.

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

References impeller::Canvas::GetCurrentLocalCullingBounds().

◆ TEST() [3/370]

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

Definition at line 24 of file canvas_unittests.cc.

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

References impeller::Canvas::GetCurrentLocalCullingBounds(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [4/370]

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

Definition at line 277 of file canvas_unittests.cc.

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

References impeller::PathBuilder::AddRect(), impeller::Canvas::ClipPath(), impeller::Canvas::GetCurrentLocalCullingBounds(), impeller::Entity::kDifference, impeller::TRect< Scalar >::MakeXYWH(), and impeller::PathBuilder::TakePath().

◆ TEST() [5/370]

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

Definition at line 325 of file canvas_unittests.cc.

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

References impeller::PathBuilder::AddRect(), impeller::Canvas::ClipPath(), impeller::Canvas::GetCurrentLocalCullingBounds(), impeller::Entity::kDifference, impeller::TRect< Scalar >::MakeXYWH(), and impeller::PathBuilder::TakePath().

◆ TEST() [6/370]

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

Definition at line 308 of file canvas_unittests.cc.

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

References impeller::PathBuilder::AddRect(), impeller::Canvas::ClipPath(), impeller::Canvas::GetCurrentLocalCullingBounds(), impeller::Entity::kDifference, impeller::TRect< Scalar >::MakeXYWH(), and impeller::PathBuilder::TakePath().

◆ TEST() [7/370]

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

Definition at line 291 of file canvas_unittests.cc.

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

References impeller::PathBuilder::AddRect(), impeller::Canvas::ClipPath(), impeller::Canvas::GetCurrentLocalCullingBounds(), impeller::Entity::kIntersect, impeller::TRect< Scalar >::MakeXYWH(), and impeller::PathBuilder::TakePath().

◆ TEST() [8/370]

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

Definition at line 261 of file canvas_unittests.cc.

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

References impeller::PathBuilder::AddRect(), impeller::Canvas::ClipPath(), impeller::Canvas::GetCurrentLocalCullingBounds(), impeller::Entity::kIntersect, impeller::TRect< Scalar >::MakeXYWH(), and impeller::PathBuilder::TakePath().

◆ TEST() [9/370]

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

Definition at line 98 of file canvas_unittests.cc.

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

References impeller::Canvas::ClipRect(), impeller::Canvas::GetCurrentLocalCullingBounds(), impeller::Entity::kDifference, and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [10/370]

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

Definition at line 65 of file canvas_unittests.cc.

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

References impeller::Canvas::ClipRect(), impeller::Canvas::GetCurrentLocalCullingBounds(), impeller::Entity::kDifference, and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [11/370]

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

Definition at line 158 of file canvas_unittests.cc.

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

References impeller::Canvas::ClipRect(), impeller::Canvas::GetCurrentLocalCullingBounds(), impeller::Entity::kDifference, and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [12/370]

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

Definition at line 86 of file canvas_unittests.cc.

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

References impeller::Canvas::ClipRect(), impeller::Canvas::GetCurrentLocalCullingBounds(), impeller::Entity::kDifference, and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [13/370]

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

Definition at line 146 of file canvas_unittests.cc.

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

References impeller::Canvas::ClipRect(), impeller::Canvas::GetCurrentLocalCullingBounds(), impeller::Entity::kDifference, and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [14/370]

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

Definition at line 110 of file canvas_unittests.cc.

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

References impeller::Canvas::ClipRect(), impeller::Canvas::GetCurrentLocalCullingBounds(), impeller::Entity::kDifference, and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [15/370]

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

Definition at line 122 of file canvas_unittests.cc.

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

References impeller::Canvas::ClipRect(), impeller::Canvas::GetCurrentLocalCullingBounds(), impeller::Entity::kDifference, and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [16/370]

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

Definition at line 134 of file canvas_unittests.cc.

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

References impeller::Canvas::ClipRect(), impeller::Canvas::GetCurrentLocalCullingBounds(), impeller::Entity::kDifference, and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [17/370]

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

Definition at line 74 of file canvas_unittests.cc.

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

References impeller::Canvas::ClipRect(), impeller::Canvas::GetCurrentLocalCullingBounds(), impeller::Entity::kIntersect, and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [18/370]

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

Definition at line 55 of file canvas_unittests.cc.

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

References impeller::Canvas::ClipRect(), impeller::Canvas::GetCurrentLocalCullingBounds(), impeller::Entity::kIntersect, and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [19/370]

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

Definition at line 180 of file canvas_unittests.cc.

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

References impeller::Canvas::ClipRRect(), impeller::Canvas::GetCurrentLocalCullingBounds(), impeller::Entity::kDifference, and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [20/370]

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

Definition at line 249 of file canvas_unittests.cc.

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

References impeller::Canvas::ClipRRect(), impeller::Canvas::GetCurrentLocalCullingBounds(), impeller::Entity::kDifference, and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [21/370]

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

Definition at line 237 of file canvas_unittests.cc.

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

References impeller::Canvas::ClipRRect(), impeller::Canvas::GetCurrentLocalCullingBounds(), impeller::Entity::kDifference, and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [22/370]

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

Definition at line 201 of file canvas_unittests.cc.

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

References impeller::Canvas::ClipRRect(), impeller::Canvas::GetCurrentLocalCullingBounds(), impeller::Entity::kDifference, and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [23/370]

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

Definition at line 225 of file canvas_unittests.cc.

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

References impeller::Canvas::ClipRRect(), impeller::Canvas::GetCurrentLocalCullingBounds(), impeller::Entity::kDifference, and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [24/370]

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

Definition at line 213 of file canvas_unittests.cc.

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

References impeller::Canvas::ClipRRect(), impeller::Canvas::GetCurrentLocalCullingBounds(), impeller::Entity::kDifference, and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [25/370]

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

Definition at line 189 of file canvas_unittests.cc.

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

References impeller::Canvas::ClipRRect(), impeller::Canvas::GetCurrentLocalCullingBounds(), impeller::Entity::kIntersect, and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [26/370]

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

Definition at line 170 of file canvas_unittests.cc.

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

References impeller::Canvas::ClipRRect(), impeller::Canvas::GetCurrentLocalCullingBounds(), impeller::Entity::kIntersect, and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [27/370]

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

Definition at line 44 of file canvas_unittests.cc.

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

References impeller::Canvas::GetCurrentLocalCullingBounds(), impeller::TRect< Scalar >::MakeXYWH(), and impeller::Canvas::Scale().

◆ TEST() [28/370]

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

Definition at line 33 of file canvas_unittests.cc.

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

References impeller::Canvas::GetCurrentLocalCullingBounds(), impeller::TRect< Scalar >::MakeXYWH(), and impeller::Canvas::Translate().

◆ TEST() [29/370]

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

Definition at line 16 of file allocator_unittests.cc.

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

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

◆ TEST() [30/370]

impeller::testing::TEST ( AllocatorVKTest  ,
MemoryTypeSelectionSingleHeap   
)

Definition at line 35 of file allocator_vk_unittests.cc.

35  {
36  vk::PhysicalDeviceMemoryProperties properties;
37  properties.memoryTypeCount = 1;
38  properties.memoryHeapCount = 1;
39  properties.memoryTypes[0].heapIndex = 0;
40  properties.memoryTypes[0].propertyFlags =
41  vk::MemoryPropertyFlagBits::eDeviceLocal;
42  properties.memoryHeaps[0].size = 1024 * 1024 * 1024;
43  properties.memoryHeaps[0].flags = vk::MemoryHeapFlagBits::eDeviceLocal;
44 
45  EXPECT_EQ(AllocatorVK::FindMemoryTypeIndex(1, properties), 0);
46  EXPECT_EQ(AllocatorVK::FindMemoryTypeIndex(2, properties), -1);
47  EXPECT_EQ(AllocatorVK::FindMemoryTypeIndex(3, properties), 0);
48 }

References impeller::AllocatorVK::FindMemoryTypeIndex().

◆ TEST() [31/370]

impeller::testing::TEST ( AllocatorVKTest  ,
MemoryTypeSelectionTwoHeap   
)

Definition at line 50 of file allocator_vk_unittests.cc.

50  {
51  vk::PhysicalDeviceMemoryProperties properties;
52  properties.memoryTypeCount = 2;
53  properties.memoryHeapCount = 2;
54  properties.memoryTypes[0].heapIndex = 0;
55  properties.memoryTypes[0].propertyFlags =
56  vk::MemoryPropertyFlagBits::eHostVisible;
57  properties.memoryHeaps[0].size = 1024 * 1024 * 1024;
58  properties.memoryHeaps[0].flags = vk::MemoryHeapFlagBits::eDeviceLocal;
59 
60  properties.memoryTypes[1].heapIndex = 1;
61  properties.memoryTypes[1].propertyFlags =
62  vk::MemoryPropertyFlagBits::eDeviceLocal;
63  properties.memoryHeaps[1].size = 1024 * 1024 * 1024;
64  properties.memoryHeaps[1].flags = vk::MemoryHeapFlagBits::eDeviceLocal;
65 
66  // First fails because this only looks for eDeviceLocal.
67  EXPECT_EQ(AllocatorVK::FindMemoryTypeIndex(1, properties), -1);
68  EXPECT_EQ(AllocatorVK::FindMemoryTypeIndex(2, properties), 1);
69  EXPECT_EQ(AllocatorVK::FindMemoryTypeIndex(3, properties), 1);
70  EXPECT_EQ(AllocatorVK::FindMemoryTypeIndex(4, properties), -1);
71 }

References impeller::AllocatorVK::FindMemoryTypeIndex().

◆ TEST() [32/370]

impeller::testing::TEST ( AllocatorVKTest  ,
ToVKImageUsageFlags   
)

Definition at line 16 of file allocator_vk_unittests.cc.

16  {
17  EXPECT_EQ(AllocatorVK::ToVKImageUsageFlags(
18  PixelFormat::kR8G8B8A8UNormInt,
19  static_cast<TextureUsageMask>(TextureUsage::kRenderTarget),
20  StorageMode::kDeviceTransient,
21  /*supports_memoryless_textures=*/true),
22  vk::ImageUsageFlagBits::eInputAttachment |
23  vk::ImageUsageFlagBits::eColorAttachment |
24  vk::ImageUsageFlagBits::eTransientAttachment);
25 
26  EXPECT_EQ(AllocatorVK::ToVKImageUsageFlags(
27  PixelFormat::kD24UnormS8Uint,
28  static_cast<TextureUsageMask>(TextureUsage::kRenderTarget),
29  StorageMode::kDeviceTransient,
30  /*supports_memoryless_textures=*/true),
31  vk::ImageUsageFlagBits::eDepthStencilAttachment |
32  vk::ImageUsageFlagBits::eTransientAttachment);
33 }

References impeller::kD24UnormS8Uint, impeller::kDeviceTransient, impeller::kR8G8B8A8UNormInt, impeller::kRenderTarget, and impeller::AllocatorVK::ToVKImageUsageFlags().

◆ TEST() [33/370]

impeller::testing::TEST ( BaseTest  ,
CanUseTypedMasks   
)

Definition at line 266 of file base_unittests.cc.

266  {
267  {
268  MyMask mask;
269  ASSERT_EQ(static_cast<uint32_t>(mask), 0u);
270  ASSERT_FALSE(mask);
271  }
272 
273  {
274  MyMask mask(MyMaskBits::kBar);
275  ASSERT_EQ(static_cast<uint32_t>(mask), 1u);
276  ASSERT_TRUE(mask);
277  }
278 
279  {
280  MyMask mask2(MyMaskBits::kBar);
281  MyMask mask(mask2);
282  ASSERT_EQ(static_cast<uint32_t>(mask), 1u);
283  ASSERT_TRUE(mask);
284  }
285 
286  {
287  MyMask mask2(MyMaskBits::kBar);
288  MyMask mask(std::move(mask2)); // NOLINT
289  ASSERT_EQ(static_cast<uint32_t>(mask), 1u);
290  ASSERT_TRUE(mask);
291  }
292 
293  ASSERT_LT(MyMaskBits::kBar, MyMaskBits::kBaz);
294  ASSERT_LE(MyMaskBits::kBar, MyMaskBits::kBaz);
295  ASSERT_GT(MyMaskBits::kBaz, MyMaskBits::kBar);
296  ASSERT_GE(MyMaskBits::kBaz, MyMaskBits::kBar);
297  ASSERT_EQ(MyMaskBits::kBaz, MyMaskBits::kBaz);
298  ASSERT_NE(MyMaskBits::kBaz, MyMaskBits::kBang);
299 
300  {
301  MyMask m1(MyMaskBits::kBar);
302  MyMask m2(MyMaskBits::kBaz);
303  ASSERT_EQ(static_cast<uint32_t>(m1 & m2), 0u);
304  ASSERT_FALSE(m1 & m2);
305  }
306 
307  {
308  MyMask m1(MyMaskBits::kBar);
309  MyMask m2(MyMaskBits::kBaz);
310  ASSERT_EQ(static_cast<uint32_t>(m1 | m2), ((1u << 0u) | (1u << 1u)));
311  ASSERT_TRUE(m1 | m2);
312  }
313 
314  {
315  MyMask m1(MyMaskBits::kBar);
316  MyMask m2(MyMaskBits::kBaz);
317  ASSERT_EQ(static_cast<uint32_t>(m1 ^ m2), ((1u << 0u) ^ (1u << 1u)));
318  ASSERT_TRUE(m1 ^ m2);
319  }
320 
321  {
322  MyMask m1(MyMaskBits::kBar);
323  ASSERT_EQ(static_cast<uint32_t>(~m1), (~(1u << 0u)));
324  ASSERT_TRUE(m1);
325  }
326 
327  {
328  MyMask m1 = MyMaskBits::kBar;
329  MyMask m2 = MyMaskBits::kBaz;
330  m2 = m1;
331  ASSERT_EQ(m2, MyMaskBits::kBar);
332  }
333 
334  {
335  MyMask m = MyMaskBits::kBar | MyMaskBits::kBaz;
336  ASSERT_TRUE(m);
337  }
338 
339  {
340  MyMask m = MyMaskBits::kBar & MyMaskBits::kBaz;
341  ASSERT_FALSE(m);
342  }
343 
344  {
345  MyMask m = MyMaskBits::kBar ^ MyMaskBits::kBaz;
346  ASSERT_TRUE(m);
347  }
348 
349  {
350  MyMask m = ~MyMaskBits::kBar;
351  ASSERT_TRUE(m);
352  }
353 
354  {
355  MyMask m1 = MyMaskBits::kBar;
356  MyMask m2 = MyMaskBits::kBaz;
357  m2 |= m1;
358  ASSERT_EQ(m1, MyMaskBits::kBar);
359  MyMask pred = MyMaskBits::kBar | MyMaskBits::kBaz;
360  ASSERT_EQ(m2, pred);
361  }
362 
363  {
364  MyMask m1 = MyMaskBits::kBar;
365  MyMask m2 = MyMaskBits::kBaz;
366  m2 &= m1;
367  ASSERT_EQ(m1, MyMaskBits::kBar);
368  MyMask pred = MyMaskBits::kBar & MyMaskBits::kBaz;
369  ASSERT_EQ(m2, pred);
370  }
371 
372  {
373  MyMask m1 = MyMaskBits::kBar;
374  MyMask m2 = MyMaskBits::kBaz;
375  m2 ^= m1;
376  ASSERT_EQ(m1, MyMaskBits::kBar);
377  MyMask pred = MyMaskBits::kBar ^ MyMaskBits::kBaz;
378  ASSERT_EQ(m2, pred);
379  }
380 
381  {
382  MyMask x = MyMaskBits::kBar;
383  MyMask m = x | MyMaskBits::kBaz;
384  ASSERT_TRUE(m);
385  }
386 
387  {
388  MyMask x = MyMaskBits::kBar;
389  MyMask m = MyMaskBits::kBaz | x;
390  ASSERT_TRUE(m);
391  }
392 
393  {
394  MyMask x = MyMaskBits::kBar;
395  MyMask m = x & MyMaskBits::kBaz;
396  ASSERT_FALSE(m);
397  }
398 
399  {
400  MyMask x = MyMaskBits::kBar;
401  MyMask m = MyMaskBits::kBaz & x;
402  ASSERT_FALSE(m);
403  }
404 
405  {
406  MyMask x = MyMaskBits::kBar;
407  MyMask m = x ^ MyMaskBits::kBaz;
408  ASSERT_TRUE(m);
409  }
410 
411  {
412  MyMask x = MyMaskBits::kBar;
413  MyMask m = MyMaskBits::kBaz ^ x;
414  ASSERT_TRUE(m);
415  }
416 
417  {
418  MyMask x = MyMaskBits::kBar;
419  MyMask m = ~x;
420  ASSERT_TRUE(m);
421  }
422 
423  {
424  MyMaskBits x = MyMaskBits::kBar;
425  MyMask m = MyMaskBits::kBaz;
426  ASSERT_TRUE(x < m);
427  ASSERT_TRUE(x <= m);
428  }
429 
430  {
431  MyMaskBits x = MyMaskBits::kBar;
432  MyMask m = MyMaskBits::kBaz;
433  ASSERT_FALSE(x == m);
434  }
435 
436  {
437  MyMaskBits x = MyMaskBits::kBar;
438  MyMask m = MyMaskBits::kBaz;
439  ASSERT_TRUE(x != m);
440  }
441 
442  {
443  MyMaskBits x = MyMaskBits::kBar;
444  MyMask m = MyMaskBits::kBaz;
445  ASSERT_FALSE(x > m);
446  ASSERT_FALSE(x >= m);
447  }
448 }

References impeller::kBang, impeller::kBar, and impeller::kBaz.

◆ TEST() [34/370]

impeller::testing::TEST ( BaseTest  ,
NoExceptionPromiseEmpty   
)

Definition at line 257 of file base_unittests.cc.

257  {
258  auto wrapper = std::make_shared<NoExceptionPromise<int>>();
259  std::future future = wrapper->get_future();
260 
261  // Destroy the empty promise with the future still pending. Verify that the
262  // process does not abort while destructing the promise.
263  wrapper.reset();
264 }

◆ TEST() [35/370]

impeller::testing::TEST ( BaseTest  ,
NoExceptionPromiseValue   
)

Definition at line 250 of file base_unittests.cc.

250  {
251  NoExceptionPromise<int> wrapper;
252  std::future future = wrapper.get_future();
253  wrapper.set_value(123);
254  ASSERT_EQ(future.get(), 123);
255 }

References impeller::NoExceptionPromise< T >::get_future(), and impeller::NoExceptionPromise< T >::set_value().

◆ TEST() [36/370]

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

Definition at line 49 of file blit_command_vk_unittests.cc.

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

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

◆ TEST() [37/370]

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

Definition at line 32 of file blit_command_vk_unittests.cc.

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

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

◆ TEST() [38/370]

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  .format = PixelFormat::kR8G8B8A8UNormInt,
20  .size = ISize(100, 100),
21  });
22  cmd.destination = context->GetResourceAllocator()->CreateTexture({
23  .format = PixelFormat::kR8G8B8A8UNormInt,
24  .size = ISize(100, 100),
25  });
26  bool result = cmd.Encode(*encoder.get());
27  EXPECT_TRUE(result);
28  EXPECT_TRUE(encoder->IsTracking(cmd.source));
29  EXPECT_TRUE(encoder->IsTracking(cmd.destination));
30 }

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

◆ TEST() [39/370]

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

Definition at line 67 of file blit_command_vk_unittests.cc.

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

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

◆ TEST() [40/370]

impeller::testing::TEST ( CanvasRecorder  ,
ClipOval   
)

Definition at line 220 of file canvas_recorder_unittests.cc.

220  {
221  CanvasRecorder<Serializer> recorder;
222  recorder.ClipOval({});
223  ASSERT_EQ(recorder.GetSerializer().last_op_, CanvasRecorderOp::kClipOval);
224 }

References impeller::kClipOval.

◆ TEST() [41/370]

impeller::testing::TEST ( CanvasRecorder  ,
ClipPath   
)

Definition at line 208 of file canvas_recorder_unittests.cc.

208  {
209  CanvasRecorder<Serializer> recorder;
210  recorder.ClipPath({});
211  ASSERT_EQ(recorder.GetSerializer().last_op_, CanvasRecorderOp::kClipPath);
212 }

References impeller::kClipPath.

◆ TEST() [42/370]

impeller::testing::TEST ( CanvasRecorder  ,
ClipRect   
)

Definition at line 214 of file canvas_recorder_unittests.cc.

214  {
215  CanvasRecorder<Serializer> recorder;
216  recorder.ClipRect({});
217  ASSERT_EQ(recorder.GetSerializer().last_op_, CanvasRecorderOp::kClipRect);
218 }

References impeller::kClipRect.

◆ TEST() [43/370]

impeller::testing::TEST ( CanvasRecorder  ,
ClipRRect   
)

Definition at line 226 of file canvas_recorder_unittests.cc.

226  {
227  CanvasRecorder<Serializer> recorder;
228  recorder.ClipRRect({}, {});
229  ASSERT_EQ(recorder.GetSerializer().last_op_, CanvasRecorderOp::kClipRRect);
230 }

References impeller::kClipRRect.

◆ TEST() [44/370]

impeller::testing::TEST ( CanvasRecorder  ,
Concat   
)

Definition at line 105 of file canvas_recorder_unittests.cc.

105  {
106  CanvasRecorder<Serializer> recorder;
107  recorder.Concat(Matrix());
108  ASSERT_EQ(recorder.GetSerializer().last_op_, CanvasRecorderOp::kConcat);
109 }

References impeller::kConcat.

◆ TEST() [45/370]

impeller::testing::TEST ( CanvasRecorder  ,
DrawAtlas   
)

Definition at line 247 of file canvas_recorder_unittests.cc.

247  {
248  CanvasRecorder<Serializer> recorder;
249  recorder.DrawAtlas({}, {}, {}, {}, {}, {}, {}, {});
250  ASSERT_EQ(recorder.GetSerializer().last_op_, CanvasRecorderOp::kDrawAtlas);
251 }

References impeller::kDrawAtlas.

◆ TEST() [46/370]

impeller::testing::TEST ( CanvasRecorder  ,
DrawCircle   
)

Definition at line 183 of file canvas_recorder_unittests.cc.

183  {
184  CanvasRecorder<Serializer> recorder;
185  recorder.DrawCircle(Point(), 0, Paint());
186  ASSERT_EQ(recorder.GetSerializer().last_op_, CanvasRecorderOp::kDrawCircle);
187 }

References impeller::kDrawCircle.

◆ TEST() [47/370]

impeller::testing::TEST ( CanvasRecorder  ,
DrawImage   
)

Definition at line 195 of file canvas_recorder_unittests.cc.

195  {
196  CanvasRecorder<Serializer> recorder;
197  recorder.DrawImage({}, {}, {}, {});
198  ASSERT_EQ(recorder.GetSerializer().last_op_, CanvasRecorderOp::kDrawImage);
199 }

References impeller::kDrawImage.

◆ TEST() [48/370]

impeller::testing::TEST ( CanvasRecorder  ,
DrawImageRect   
)

Definition at line 201 of file canvas_recorder_unittests.cc.

201  {
202  CanvasRecorder<Serializer> recorder;
203  recorder.DrawImageRect({}, {}, {}, {}, {}, SourceRectConstraint::kFast);
204  ASSERT_EQ(recorder.GetSerializer().last_op_,
206 }

References impeller::kDrawImageRect, and impeller::kFast.

◆ TEST() [49/370]

impeller::testing::TEST ( CanvasRecorder  ,
DrawLine   
)

Definition at line 159 of file canvas_recorder_unittests.cc.

159  {
160  CanvasRecorder<Serializer> recorder;
161  recorder.DrawLine(Point(), Point(), Paint());
162  ASSERT_EQ(recorder.GetSerializer().last_op_, CanvasRecorderOp::kDrawLine);
163 }

References impeller::kDrawLine.

◆ TEST() [50/370]

impeller::testing::TEST ( CanvasRecorder  ,
DrawOval   
)

Definition at line 171 of file canvas_recorder_unittests.cc.

171  {
172  CanvasRecorder<Serializer> recorder;
173  recorder.DrawOval(Rect(), Paint());
174  ASSERT_EQ(recorder.GetSerializer().last_op_, CanvasRecorderOp::kDrawOval);
175 }

References impeller::kDrawOval.

◆ TEST() [51/370]

impeller::testing::TEST ( CanvasRecorder  ,
DrawPaint   
)

Definition at line 153 of file canvas_recorder_unittests.cc.

153  {
154  CanvasRecorder<Serializer> recorder;
155  recorder.DrawPaint(Paint());
156  ASSERT_EQ(recorder.GetSerializer().last_op_, CanvasRecorderOp::kDrawPaint);
157 }

References impeller::kDrawPaint.

◆ TEST() [52/370]

impeller::testing::TEST ( CanvasRecorder  ,
DrawPath   
)

Definition at line 147 of file canvas_recorder_unittests.cc.

147  {
148  CanvasRecorder<Serializer> recorder;
149  recorder.DrawPath(Path(), Paint());
150  ASSERT_EQ(recorder.GetSerializer().last_op_, CanvasRecorderOp::kDrawPath);
151 }

References impeller::kDrawPath.

◆ TEST() [53/370]

impeller::testing::TEST ( CanvasRecorder  ,
DrawPoints   
)

Definition at line 189 of file canvas_recorder_unittests.cc.

189  {
190  CanvasRecorder<Serializer> recorder;
191  recorder.DrawPoints(std::vector<Point>{}, 0, Paint(), PointStyle::kRound);
192  ASSERT_EQ(recorder.GetSerializer().last_op_, CanvasRecorderOp::kDrawPoints);
193 }

References impeller::kDrawPoints, and impeller::kRound.

◆ TEST() [54/370]

impeller::testing::TEST ( CanvasRecorder  ,
DrawRect   
)

Definition at line 165 of file canvas_recorder_unittests.cc.

165  {
166  CanvasRecorder<Serializer> recorder;
167  recorder.DrawRect(Rect(), Paint());
168  ASSERT_EQ(recorder.GetSerializer().last_op_, CanvasRecorderOp::kDrawRect);
169 }

References impeller::kDrawRect.

◆ TEST() [55/370]

impeller::testing::TEST ( CanvasRecorder  ,
DrawRRect   
)

Definition at line 177 of file canvas_recorder_unittests.cc.

177  {
178  CanvasRecorder<Serializer> recorder;
179  recorder.DrawRRect(Rect(), {}, Paint());
180  ASSERT_EQ(recorder.GetSerializer().last_op_, CanvasRecorderOp::kDrawRRect);
181 }

References impeller::kDrawRRect.

◆ TEST() [56/370]

impeller::testing::TEST ( CanvasRecorder  ,
DrawTextFrame   
)

Definition at line 232 of file canvas_recorder_unittests.cc.

232  {
233  CanvasRecorder<Serializer> recorder;
234  recorder.DrawTextFrame({}, {}, {});
235  ASSERT_EQ(recorder.GetSerializer().last_op_,
237 }

References impeller::kDrawTextFrame.

◆ TEST() [57/370]

impeller::testing::TEST ( CanvasRecorder  ,
DrawVertices   
)

Definition at line 239 of file canvas_recorder_unittests.cc.

239  {
240  CanvasRecorder<Serializer> recorder;
241  auto geometry = std::shared_ptr<VerticesGeometry>(
242  new VerticesGeometry({}, {}, {}, {}, {}, {}));
243  recorder.DrawVertices(geometry, {}, {});
244  ASSERT_EQ(recorder.GetSerializer().last_op_, CanvasRecorderOp::kDrawVertices);
245 }

References impeller::kDrawVertices.

◆ TEST() [58/370]

impeller::testing::TEST ( CanvasRecorder  ,
PreConcat   
)

Definition at line 111 of file canvas_recorder_unittests.cc.

111  {
112  CanvasRecorder<Serializer> recorder;
113  recorder.PreConcat(Matrix());
114  ASSERT_EQ(recorder.GetSerializer().last_op_, CanvasRecorderOp::kPreConcat);
115 }

References impeller::kPreConcat.

◆ TEST() [59/370]

impeller::testing::TEST ( CanvasRecorder  ,
ResetTransform   
)

Definition at line 92 of file canvas_recorder_unittests.cc.

92  {
93  CanvasRecorder<Serializer> recorder;
94  recorder.ResetTransform();
95  ASSERT_EQ(recorder.GetSerializer().last_op_,
97 }

References impeller::kResetTransform.

◆ TEST() [60/370]

impeller::testing::TEST ( CanvasRecorder  ,
Restore   
)

Definition at line 78 of file canvas_recorder_unittests.cc.

78  {
79  CanvasRecorder<Serializer> recorder;
80  recorder.Restore();
81  ASSERT_EQ(recorder.GetSerializer().last_op_, CanvasRecorderOp::kRestore);
82 }

References impeller::kRestore.

◆ TEST() [61/370]

impeller::testing::TEST ( CanvasRecorder  ,
RestoreToCount   
)

Definition at line 84 of file canvas_recorder_unittests.cc.

84  {
85  CanvasRecorder<Serializer> recorder;
86  recorder.Save();
87  recorder.RestoreToCount(0);
88  ASSERT_EQ(recorder.GetSerializer().last_op_,
90 }

References impeller::kRestoreToCount.

◆ TEST() [62/370]

impeller::testing::TEST ( CanvasRecorder  ,
Rotate   
)

Definition at line 141 of file canvas_recorder_unittests.cc.

141  {
142  CanvasRecorder<Serializer> recorder;
143  recorder.Rotate(Radians(0));
144  ASSERT_EQ(recorder.GetSerializer().last_op_, CanvasRecorderOp::kRotate);
145 }

References impeller::kRotate.

◆ TEST() [63/370]

impeller::testing::TEST ( CanvasRecorder  ,
Save   
)

Definition at line 65 of file canvas_recorder_unittests.cc.

65  {
66  CanvasRecorder<Serializer> recorder;
67  recorder.Save();
68  ASSERT_EQ(recorder.GetSerializer().last_op_, CanvasRecorderOp::kSave);
69 }

References impeller::kSave.

◆ TEST() [64/370]

impeller::testing::TEST ( CanvasRecorder  ,
SaveLayer   
)

Definition at line 71 of file canvas_recorder_unittests.cc.

71  {
72  CanvasRecorder<Serializer> recorder;
73  Paint paint;
74  recorder.SaveLayer(paint);
75  ASSERT_EQ(recorder.GetSerializer().last_op_, CanvasRecorderOp::kSaveLayer);
76 }

References impeller::kSaveLayer.

◆ TEST() [65/370]

impeller::testing::TEST ( CanvasRecorder  ,
Scale2   
)

Definition at line 123 of file canvas_recorder_unittests.cc.

123  {
124  CanvasRecorder<Serializer> recorder;
125  recorder.Scale(Vector2());
126  ASSERT_EQ(recorder.GetSerializer().last_op_, CanvasRecorderOp::kScale2);
127 }

References impeller::kScale2.

◆ TEST() [66/370]

impeller::testing::TEST ( CanvasRecorder  ,
Scale3   
)

Definition at line 129 of file canvas_recorder_unittests.cc.

129  {
130  CanvasRecorder<Serializer> recorder;
131  recorder.Scale(Vector3());
132  ASSERT_EQ(recorder.GetSerializer().last_op_, CanvasRecorderOp::kScale3);
133 }

References impeller::kScale3.

◆ TEST() [67/370]

impeller::testing::TEST ( CanvasRecorder  ,
Skew   
)

Definition at line 135 of file canvas_recorder_unittests.cc.

135  {
136  CanvasRecorder<Serializer> recorder;
137  recorder.Skew(0, 0);
138  ASSERT_EQ(recorder.GetSerializer().last_op_, CanvasRecorderOp::kSkew);
139 }

References impeller::kSkew.

◆ TEST() [68/370]

impeller::testing::TEST ( CanvasRecorder  ,
Transform   
)

Definition at line 99 of file canvas_recorder_unittests.cc.

99  {
100  CanvasRecorder<Serializer> recorder;
101  recorder.Transform(Matrix());
102  ASSERT_EQ(recorder.GetSerializer().last_op_, CanvasRecorderOp::kTransform);
103 }

References impeller::kTransform.

◆ TEST() [69/370]

impeller::testing::TEST ( CanvasRecorder  ,
Translate   
)

Definition at line 117 of file canvas_recorder_unittests.cc.

117  {
118  CanvasRecorder<Serializer> recorder;
119  recorder.Translate(Vector3());
120  ASSERT_EQ(recorder.GetSerializer().last_op_, CanvasRecorderOp::kTranslate);
121 }

References impeller::kTranslate.

◆ TEST() [70/370]

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

Definition at line 32 of file capabilities_unittests.cc.

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

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

◆ TEST() [71/370]

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

Definition at line 50 of file capabilities_unittests.cc.

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

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

◆ TEST() [72/370]

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

Definition at line 60 of file capabilities_unittests.cc.

60  {
61  auto defaults = CapabilitiesBuilder().Build();
62  EXPECT_EQ(defaults->GetDefaultGlyphAtlasFormat(), PixelFormat::kUnknown);
63  auto mutated = CapabilitiesBuilder()
64  .SetDefaultGlyphAtlasFormat(PixelFormat::kA8UNormInt)
65  .Build();
66  EXPECT_EQ(mutated->GetDefaultGlyphAtlasFormat(), PixelFormat::kA8UNormInt);
67 }

References impeller::CapabilitiesBuilder::Build(), impeller::kA8UNormInt, impeller::kUnknown, and impeller::CapabilitiesBuilder::SetDefaultGlyphAtlasFormat().

◆ TEST() [73/370]

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

Definition at line 41 of file capabilities_unittests.cc.

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

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

◆ TEST() [74/370]

impeller::testing::TEST ( CapabilitiesVKTest  ,
ContextFailsInitializationForNoCombinedDepthStencilFormat   
)

Definition at line 195 of file context_vk_unittests.cc.

196  {
197  ScopedValidationDisable disable_validation;
198  const std::shared_ptr<ContextVK> context =
199  MockVulkanContextBuilder()
200  .SetPhysicalDeviceFormatPropertiesCallback(
201  [](VkPhysicalDevice physicalDevice, VkFormat format,
202  VkFormatProperties* pFormatProperties) {
203  if (format == VK_FORMAT_B8G8R8A8_UNORM) {
204  pFormatProperties->optimalTilingFeatures =
205  static_cast<VkFormatFeatureFlags>(
206  vk::FormatFeatureFlagBits::eColorAttachment);
207  }
208  // Ignore combined depth-stencil formats.
209  })
210  .Build();
211  ASSERT_EQ(context, nullptr);
212 }

◆ TEST() [75/370]

impeller::testing::TEST ( CapabilitiesVKTest  ,
ContextInitializesWithNoStencilFormat   
)

Definition at line 164 of file context_vk_unittests.cc.

164  {
165  const std::shared_ptr<ContextVK> context =
166  MockVulkanContextBuilder()
167  .SetPhysicalDeviceFormatPropertiesCallback(
168  [](VkPhysicalDevice physicalDevice, VkFormat format,
169  VkFormatProperties* pFormatProperties) {
170  if (format == VK_FORMAT_B8G8R8A8_UNORM) {
171  pFormatProperties->optimalTilingFeatures =
172  static_cast<VkFormatFeatureFlags>(
173  vk::FormatFeatureFlagBits::eColorAttachment);
174  } else if (format == VK_FORMAT_D32_SFLOAT_S8_UINT) {
175  pFormatProperties->optimalTilingFeatures =
176  static_cast<VkFormatFeatureFlags>(
177  vk::FormatFeatureFlagBits::eDepthStencilAttachment);
178  }
179  // Ignore just the stencil format.
180  })
181  .Build();
182  ASSERT_NE(context, nullptr);
183  const CapabilitiesVK* capabilites_vk =
184  reinterpret_cast<const CapabilitiesVK*>(context->GetCapabilities().get());
185  ASSERT_EQ(capabilites_vk->GetDefaultDepthStencilFormat(),
186  PixelFormat::kD32FloatS8UInt);
187  ASSERT_EQ(capabilites_vk->GetDefaultStencilFormat(),
188  PixelFormat::kD32FloatS8UInt);
189 }

References impeller::CapabilitiesVK::GetDefaultDepthStencilFormat(), impeller::CapabilitiesVK::GetDefaultStencilFormat(), and impeller::kD32FloatS8UInt.

◆ TEST() [76/370]

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

Definition at line 42 of file command_encoder_vk_unittests.cc.

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

References impeller::CommandBuffer::kCompleted.

◆ TEST() [77/370]

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

Definition at line 16 of file command_encoder_vk_unittests.cc.

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

References impeller::CommandEncoderFactoryVK::Create().

◆ TEST() [78/370]

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

Definition at line 115 of file command_pool_vk_unittests.cc.

115  {
116  auto const context = MockVulkanContextBuilder().Build();
117 
118  {
119  // Fetch a pool (which will be created).
120  auto const recycler = context->GetCommandPoolRecycler();
121  auto pool = recycler->Get();
122 
123  auto buffer = pool->CreateCommandBuffer();
124  pool->CollectCommandBuffer(std::move(buffer));
125 
126  // This normally is called at the end of a frame.
127  recycler->Dispose();
128  }
129 
130  // Wait for the pool to be reclaimed.
131  for (auto i = 0u; i < 2u; i++) {
132  auto waiter = fml::AutoResetWaitableEvent();
133  auto rattle = DeathRattle([&waiter]() { waiter.Signal(); });
134  {
135  UniqueResourceVKT<DeathRattle> resource(context->GetResourceManager(),
136  std::move(rattle));
137  }
138  waiter.Wait();
139  }
140 
141  {
142  // Create a second pool and command buffer, which should reused the existing
143  // pool and cmd buffer.
144  auto const recycler = context->GetCommandPoolRecycler();
145  auto pool = recycler->Get();
146 
147  auto buffer = pool->CreateCommandBuffer();
148  pool->CollectCommandBuffer(std::move(buffer));
149 
150  // This normally is called at the end of a frame.
151  recycler->Dispose();
152  }
153 
154  // Now check that we only ever created one pool and one command buffer.
155  auto const called = GetMockVulkanFunctions(context->GetDevice());
156  EXPECT_EQ(std::count(called->begin(), called->end(), "vkCreateCommandPool"),
157  1u);
158  EXPECT_EQ(
159  std::count(called->begin(), called->end(), "vkAllocateCommandBuffers"),
160  1u);
161 
162  context->Shutdown();
163 }

◆ TEST() [79/370]

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

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

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

impeller::testing::TEST ( ConditionVariableTest  ,
TestsCriticalSectionAfterWait   
)

Definition at line 205 of file base_unittests.cc.

205  {
206  std::vector<std::thread> threads;
207  const auto kThreadCount = 10u;
208 
209  Mutex mtx;
210  ConditionVariable cv;
211  size_t sum = 0u;
212 
213  std::condition_variable start_cv;
214  std::mutex start_mtx;
215  bool start = false;
216  auto start_predicate = [&start]() { return start; };
217  auto thread_main = [&]() {
218  {
219  std::unique_lock start_lock(start_mtx);
220  start_cv.wait(start_lock, start_predicate);
221  }
222 
223  mtx.Lock();
224  cv.Wait(mtx, []() { return true; });
225  auto old_val = sum;
226  std::this_thread::sleep_for(std::chrono::milliseconds{100u});
227  sum = old_val + 1u;
228  mtx.Unlock();
229  };
230  // Launch all threads. They will wait for the start CV to be signaled.
231  for (size_t i = 0; i < kThreadCount; i++) {
232  threads.emplace_back(thread_main);
233  }
234  // Notify all threads that the test may start.
235  {
236  {
237  std::scoped_lock start_lock(start_mtx);
238  start = true;
239  }
240  start_cv.notify_all();
241  }
242  // Join all threads.
243  ASSERT_EQ(threads.size(), kThreadCount);
244  for (size_t i = 0; i < kThreadCount; i++) {
245  threads[i].join();
246  }
247  ASSERT_EQ(sum, kThreadCount);
248 }

References impeller::ConditionVariable::Wait().

◆ TEST() [83/370]

impeller::testing::TEST ( ConditionVariableTest  ,
TestsCriticalSectionAfterWaitForUntil   
)

Definition at line 160 of file base_unittests.cc.

160  {
161  std::vector<std::thread> threads;
162  const auto kThreadCount = 10u;
163 
164  Mutex mtx;
165  ConditionVariable cv;
166  size_t sum = 0u;
167 
168  std::condition_variable start_cv;
169  std::mutex start_mtx;
170  bool start = false;
171  auto start_predicate = [&start]() { return start; };
172  auto thread_main = [&]() {
173  {
174  std::unique_lock start_lock(start_mtx);
175  start_cv.wait(start_lock, start_predicate);
176  }
177 
178  mtx.Lock();
179  cv.WaitFor(mtx, std::chrono::milliseconds{0u}, []() { return true; });
180  auto old_val = sum;
181  std::this_thread::sleep_for(std::chrono::milliseconds{100u});
182  sum = old_val + 1u;
183  mtx.Unlock();
184  };
185  // Launch all threads. They will wait for the start CV to be signaled.
186  for (size_t i = 0; i < kThreadCount; i++) {
187  threads.emplace_back(thread_main);
188  }
189  // Notify all threads that the test may start.
190  {
191  {
192  std::scoped_lock start_lock(start_mtx);
193  start = true;
194  }
195  start_cv.notify_all();
196  }
197  // Join all threads.
198  ASSERT_EQ(threads.size(), kThreadCount);
199  for (size_t i = 0; i < kThreadCount; i++) {
200  threads[i].join();
201  }
202  ASSERT_EQ(sum, kThreadCount);
203 }

References impeller::ConditionVariable::WaitFor().

◆ TEST() [84/370]

impeller::testing::TEST ( ConditionVariableTest  ,
WaitFor   
)

Definition at line 122 of file base_unittests.cc.

122  {
123  CVTest test;
124  // test.rando_ivar = 12; // <--- Static analysis error
125  for (size_t i = 0; i < 2; ++i) {
126  test.mutex.Lock(); // <--- Static analysis error without this.
127  auto result = test.cv.WaitFor(
128  test.mutex, std::chrono::milliseconds{10},
129  [&]() IPLR_REQUIRES(test.mutex) {
130  test.rando_ivar = 12; // <-- Static analysics error without the
131  // IPLR_REQUIRES on the pred.
132  return false;
133  });
134  test.mutex.Unlock();
135  ASSERT_FALSE(result);
136  }
137  Lock lock(test.mutex); // <--- Static analysis error without this.
138  // The predicate never returns true. So return has to be due to a non-spurious
139  // wake.
140  ASSERT_EQ(test.rando_ivar, 12u);
141 }

References impeller::testing::CVTest::cv, IPLR_REQUIRES, impeller::testing::CVTest::mutex, and impeller::ConditionVariable::WaitFor().

◆ TEST() [85/370]

impeller::testing::TEST ( ConditionVariableTest  ,
WaitForever   
)

Definition at line 143 of file base_unittests.cc.

143  {
144  CVTest test;
145  // test.rando_ivar = 12; // <--- Static analysis error
146  for (size_t i = 0; i < 2; ++i) {
147  test.mutex.Lock(); // <--- Static analysis error without this.
148  test.cv.Wait(test.mutex, [&]() IPLR_REQUIRES(test.mutex) {
149  test.rando_ivar = 12; // <-- Static analysics error without
150  // the IPLR_REQUIRES on the pred.
151  return true;
152  });
153  test.mutex.Unlock();
154  }
155  Lock lock(test.mutex); // <--- Static analysis error without this.
156  // The wake only happens when the predicate returns true.
157  ASSERT_EQ(test.rando_ivar, 12u);
158 }

References impeller::testing::CVTest::cv, IPLR_REQUIRES, impeller::testing::CVTest::mutex, and impeller::ConditionVariable::Wait().

◆ TEST() [86/370]

impeller::testing::TEST ( ConditionVariableTest  ,
WaitUntil   
)

Definition at line 99 of file base_unittests.cc.

99  {
100  CVTest test;
101  // test.rando_ivar = 12; // <--- Static analysis error
102  for (size_t i = 0; i < 2; ++i) {
103  test.mutex.Lock(); // <--- Static analysis error without this.
104  auto result = test.cv.WaitUntil(
105  test.mutex,
106  std::chrono::high_resolution_clock::now() +
107  std::chrono::milliseconds{10},
108  [&]() IPLR_REQUIRES(test.mutex) {
109  test.rando_ivar = 12; // <-- Static analysics error without the
110  // IPLR_REQUIRES on the pred.
111  return false;
112  });
113  test.mutex.Unlock();
114  ASSERT_FALSE(result);
115  }
116  Lock lock(test.mutex); // <--- Static analysis error without this.
117  // The predicate never returns true. So return has to be due to a non-spurious
118  // wake.
119  ASSERT_EQ(test.rando_ivar, 12u);
120 }

References impeller::testing::CVTest::cv, IPLR_REQUIRES, impeller::testing::CVTest::mutex, and impeller::ConditionVariable::WaitUntil().

◆ TEST() [87/370]

impeller::testing::TEST ( ContentContext  ,
CachesPipelines   
)

Definition at line 262 of file content_context_unittests.cc.

262  {
263  auto context = std::make_shared<FakeContext>();
264 
265  auto create_callback = [&]() {
266  return std::make_shared<FakePipeline>(context->GetPipelineLibrary(),
267  PipelineDescriptor{});
268  };
269 
270  ContentContext content_context(context, nullptr);
271  ContentContextOptions optionsA{.blend_mode = BlendMode::kSourceOver};
272  ContentContextOptions optionsB{.blend_mode = BlendMode::kSource};
273 
274  auto pipelineA = content_context.GetCachedRuntimeEffectPipeline(
275  "A", optionsA, create_callback);
276 
277  auto pipelineA2 = content_context.GetCachedRuntimeEffectPipeline(
278  "A", optionsA, create_callback);
279 
280  auto pipelineA3 = content_context.GetCachedRuntimeEffectPipeline(
281  "A", optionsB, create_callback);
282 
283  auto pipelineB = content_context.GetCachedRuntimeEffectPipeline(
284  "B", optionsB, create_callback);
285 
286  ASSERT_EQ(pipelineA.get(), pipelineA2.get());
287  ASSERT_NE(pipelineA.get(), pipelineA3.get());
288  ASSERT_NE(pipelineB.get(), pipelineA.get());
289 }

References impeller::ContentContextOptions::blend_mode, impeller::ContentContext::GetCachedRuntimeEffectPipeline(), impeller::kSource, and impeller::kSourceOver.

◆ TEST() [88/370]

impeller::testing::TEST ( ContentContext  ,
InitializeCommonlyUsedShadersIfNeeded   
)

Definition at line 337 of file content_context_unittests.cc.

337  {
338  ScopedValidationFatal fatal_validations;
339  // Set a pixel format that is larger than 32bpp.
340  auto context = std::make_shared<FakeContext>("Mali G70",
341  PixelFormat::kR16G16B16A16Float);
342  ContentContext content_context(context, nullptr);
343 
344  FakeAllocator& fake_allocator =
345  FakeAllocator::Cast(*context->GetResourceAllocator());
346 
347 #if IMPELLER_ENABLE_3D
348  EXPECT_EQ(fake_allocator.textures.size(), 2u);
349 #else
350  EXPECT_EQ(fake_allocator.textures.size(), 1u);
351 #endif // IMPELLER_ENABLE_3D
352 }

References impeller::kR16G16B16A16Float.

◆ TEST() [89/370]

impeller::testing::TEST ( ContentContext  ,
InvalidatesAllPipelinesWithSameUniqueNameOnClear   
)

Definition at line 291 of file content_context_unittests.cc.

291  {
292  auto context = std::make_shared<FakeContext>();
293  ContentContext content_context(context, nullptr);
294  ContentContextOptions optionsA{.blend_mode = BlendMode::kSourceOver};
295  ContentContextOptions optionsB{.blend_mode = BlendMode::kSource};
296 
297  auto create_callback = [&]() {
298  return std::make_shared<FakePipeline>(context->GetPipelineLibrary(),
299  PipelineDescriptor{});
300  };
301 
302  auto pipelineA = content_context.GetCachedRuntimeEffectPipeline(
303  "A", optionsA, create_callback);
304 
305  auto pipelineA2 = content_context.GetCachedRuntimeEffectPipeline(
306  "A", optionsB, create_callback);
307 
308  auto pipelineB = content_context.GetCachedRuntimeEffectPipeline(
309  "B", optionsB, create_callback);
310 
311  ASSERT_TRUE(pipelineA);
312  ASSERT_TRUE(pipelineA2);
313  ASSERT_TRUE(pipelineB);
314 
315  ASSERT_EQ(pipelineA, content_context.GetCachedRuntimeEffectPipeline(
316  "A", optionsA, create_callback));
317  ASSERT_EQ(pipelineA2, content_context.GetCachedRuntimeEffectPipeline(
318  "A", optionsB, create_callback));
319  ASSERT_EQ(pipelineB, content_context.GetCachedRuntimeEffectPipeline(
320  "B", optionsB, create_callback));
321 
322  content_context.ClearCachedRuntimeEffectPipeline("A");
323 
324  ASSERT_NE(pipelineA, content_context.GetCachedRuntimeEffectPipeline(
325  "A", optionsA, create_callback));
326  ASSERT_NE(pipelineA2, content_context.GetCachedRuntimeEffectPipeline(
327  "A", optionsB, create_callback));
328  ASSERT_EQ(pipelineB, content_context.GetCachedRuntimeEffectPipeline(
329  "B", optionsB, create_callback));
330 
331  content_context.ClearCachedRuntimeEffectPipeline("B");
332 
333  ASSERT_NE(pipelineB, content_context.GetCachedRuntimeEffectPipeline(
334  "B", optionsB, create_callback));
335 }

References impeller::ContentContextOptions::blend_mode, impeller::ContentContext::ClearCachedRuntimeEffectPipeline(), impeller::ContentContext::GetCachedRuntimeEffectPipeline(), impeller::kSource, and impeller::kSourceOver.

◆ TEST() [90/370]

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

Definition at line 132 of file context_vk_unittests.cc.

132  {
133  // The mocked methods don't report the presence of a validation layer but we
134  // explicitly ask for validation. Context creation should continue anyway.
135  auto context = MockVulkanContextBuilder()
136  .SetSettingsCallback([](auto& settings) {
137  settings.enable_validation = true;
138  })
139  .Build();
140  ASSERT_NE(context, nullptr);
141  const CapabilitiesVK* capabilites_vk =
142  reinterpret_cast<const CapabilitiesVK*>(context->GetCapabilities().get());
143  ASSERT_FALSE(capabilites_vk->AreValidationsEnabled());
144 }

References impeller::CapabilitiesVK::AreValidationsEnabled().

◆ TEST() [91/370]

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

Definition at line 146 of file context_vk_unittests.cc.

146  {
147  auto context =
148  MockVulkanContextBuilder()
149  .SetSettingsCallback(
150  [](auto& settings) { settings.enable_validation = true; })
151  .SetInstanceExtensions(
152  {"VK_KHR_surface", "VK_MVK_macos_surface", "VK_EXT_debug_utils"})
153  .SetInstanceLayers({"VK_LAYER_KHRONOS_validation"})
154  .Build();
155  ASSERT_NE(context, nullptr);
156  const CapabilitiesVK* capabilites_vk =
157  reinterpret_cast<const CapabilitiesVK*>(context->GetCapabilities().get());
158  ASSERT_TRUE(capabilites_vk->AreValidationsEnabled());
159 }

References impeller::CapabilitiesVK::AreValidationsEnabled().

◆ TEST() [92/370]

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

Definition at line 16 of file context_vk_unittests.cc.

16  {
17  EXPECT_EQ(ContextVK::ChooseThreadCountForWorkers(100u), 4u);
18  EXPECT_EQ(ContextVK::ChooseThreadCountForWorkers(9u), 4u);
19  EXPECT_EQ(ContextVK::ChooseThreadCountForWorkers(8u), 4u);
20  EXPECT_EQ(ContextVK::ChooseThreadCountForWorkers(7u), 3u);
21  EXPECT_EQ(ContextVK::ChooseThreadCountForWorkers(6u), 3u);
22  EXPECT_EQ(ContextVK::ChooseThreadCountForWorkers(5u), 2u);
23  EXPECT_EQ(ContextVK::ChooseThreadCountForWorkers(4u), 2u);
24  EXPECT_EQ(ContextVK::ChooseThreadCountForWorkers(3u), 1u);
25  EXPECT_EQ(ContextVK::ChooseThreadCountForWorkers(2u), 1u);
26  EXPECT_EQ(ContextVK::ChooseThreadCountForWorkers(1u), 1u);
27 }

References impeller::ContextVK::ChooseThreadCountForWorkers().

◆ TEST() [93/370]

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

Definition at line 75 of file context_vk_unittests.cc.

75  {
76  std::shared_ptr<Pipeline<PipelineDescriptor>> pipeline;
77  std::shared_ptr<std::vector<std::string>> functions;
78  {
79  std::shared_ptr<ContextVK> context = MockVulkanContextBuilder().Build();
80  PipelineDescriptor pipeline_desc;
81  pipeline_desc.SetVertexDescriptor(std::make_shared<VertexDescriptor>());
82  PipelineFuture<PipelineDescriptor> pipeline_future =
83  context->GetPipelineLibrary()->GetPipeline(pipeline_desc);
84  pipeline = pipeline_future.Get();
85  ASSERT_TRUE(pipeline);
86  functions = GetMockVulkanFunctions(context->GetDevice());
87  ASSERT_TRUE(std::find(functions->begin(), functions->end(),
88  "vkCreateGraphicsPipelines") != functions->end());
89  }
90  ASSERT_TRUE(std::find(functions->begin(), functions->end(),
91  "vkDestroyDevice") != functions->end());
92 }

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

◆ TEST() [94/370]

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

Definition at line 116 of file context_vk_unittests.cc.

116  {
117  std::shared_ptr<PipelineLibrary> pipeline_library;
118  std::shared_ptr<std::vector<std::string>> functions;
119  {
120  std::shared_ptr<ContextVK> context = MockVulkanContextBuilder().Build();
121  PipelineDescriptor pipeline_desc;
122  pipeline_desc.SetVertexDescriptor(std::make_shared<VertexDescriptor>());
123  pipeline_library = context->GetPipelineLibrary();
124  functions = GetMockVulkanFunctions(context->GetDevice());
125  ASSERT_TRUE(std::find(functions->begin(), functions->end(),
126  "vkCreatePipelineCache") != functions->end());
127  }
128  ASSERT_TRUE(std::find(functions->begin(), functions->end(),
129  "vkDestroyDevice") != functions->end());
130 }

References impeller::PipelineDescriptor::SetVertexDescriptor().

◆ TEST() [95/370]

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

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;
32  {
33  std::shared_ptr<ContextVK> context = MockVulkanContextBuilder().Build();
34  auto const pool = context->GetCommandPoolRecycler()->Get();
35  weak_pool = pool;
36  weak_context = context;
37  ASSERT_TRUE(weak_pool.lock());
38  ASSERT_TRUE(weak_context.lock());
39  }
40  ASSERT_FALSE(weak_pool.lock());
41  ASSERT_FALSE(weak_context.lock());
42 }

◆ TEST() [96/370]

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

Definition at line 44 of file context_vk_unittests.cc.

44  {
45  std::weak_ptr<ContextVK> weak_context;
46  std::weak_ptr<CommandPoolVK> weak_pool_main;
47 
48  std::shared_ptr<ContextVK> context = MockVulkanContextBuilder().Build();
49  weak_pool_main = context->GetCommandPoolRecycler()->Get();
50  weak_context = context;
51  ASSERT_TRUE(weak_pool_main.lock());
52  ASSERT_TRUE(weak_context.lock());
53 
54  // Start a second thread that obtains a command pool.
55  fml::AutoResetWaitableEvent latch1, latch2;
56  std::weak_ptr<CommandPoolVK> weak_pool_thread;
57  std::thread thread([&]() {
58  weak_pool_thread = context->GetCommandPoolRecycler()->Get();
59  latch1.Signal();
60  latch2.Wait();
61  });
62 
63  // Delete the ContextVK on the main thread.
64  latch1.Wait();
65  context.reset();
66  ASSERT_FALSE(weak_pool_main.lock());
67  ASSERT_FALSE(weak_context.lock());
68 
69  // Stop the second thread and check that its command pool has been deleted.
70  latch2.Signal();
71  thread.join();
72  ASSERT_FALSE(weak_pool_thread.lock());
73 }

◆ TEST() [97/370]

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

Definition at line 94 of file context_vk_unittests.cc.

94  {
95  std::shared_ptr<const ShaderFunction> shader_function;
96  std::shared_ptr<std::vector<std::string>> functions;
97  {
98  std::shared_ptr<ContextVK> context = MockVulkanContextBuilder().Build();
99  PipelineDescriptor pipeline_desc;
100  pipeline_desc.SetVertexDescriptor(std::make_shared<VertexDescriptor>());
101  std::vector<uint8_t> data = {0x03, 0x02, 0x23, 0x07};
102  context->GetShaderLibrary()->RegisterFunction(
103  "foobar_fragment_main", ShaderStage::kFragment,
104  std::make_shared<fml::DataMapping>(data), [](bool) {});
105  shader_function = context->GetShaderLibrary()->GetFunction(
106  "foobar_fragment_main", ShaderStage::kFragment);
107  ASSERT_TRUE(shader_function);
108  functions = GetMockVulkanFunctions(context->GetDevice());
109  ASSERT_TRUE(std::find(functions->begin(), functions->end(),
110  "vkCreateShaderModule") != functions->end());
111  }
112  ASSERT_TRUE(std::find(functions->begin(), functions->end(),
113  "vkDestroyDevice") != functions->end());
114 }

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

◆ TEST() [98/370]

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

Definition at line 214 of file context_vk_unittests.cc.

214  {
215  const std::shared_ptr<ContextVK> context = MockVulkanContextBuilder().Build();
216 
217  context->SetOffscreenFormat(PixelFormat::kR8G8B8A8UNormInt);
218  context->InitializeCommonlyUsedShadersIfNeeded();
219 
220  auto functions = GetMockVulkanFunctions(context->GetDevice());
221  ASSERT_TRUE(std::find(functions->begin(), functions->end(),
222  "vkCreateRenderPass") != functions->end());
223 }

References impeller::kR8G8B8A8UNormInt.

◆ TEST() [99/370]

impeller::testing::TEST ( DescriptorPoolRecyclerVKTest  ,
GetDescriptorPoolRecyclerCreatesNewPools   
)

Definition at line 14 of file descriptor_pool_vk_unittests.cc.

14  {
15  auto const context = MockVulkanContextBuilder().Build();
16 
17  auto const pool1 = context->GetDescriptorPoolRecycler()->Get();
18  auto const pool2 = context->GetDescriptorPoolRecycler()->Get();
19 
20  // The two descriptor pools should be different.
21  EXPECT_NE(pool1.get(), pool2.get());
22 
23  context->Shutdown();
24 }

◆ TEST() [100/370]

impeller::testing::TEST ( DescriptorPoolRecyclerVKTest  ,
ReclaimDropsDescriptorPoolIfSizeIsExceeded   
)

Definition at line 85 of file descriptor_pool_vk_unittests.cc.

85  {
86  auto const context = MockVulkanContextBuilder().Build();
87 
88  // Create 33 pools
89  {
90  std::vector<std::unique_ptr<DescriptorPoolVK>> pools;
91  for (auto i = 0u; i < 33; i++) {
92  auto pool = std::make_unique<DescriptorPoolVK>(context);
93  pool->AllocateDescriptorSets({}, *context);
94  pools.push_back(std::move(pool));
95  }
96  }
97 
98  // See note above.
99  for (auto i = 0u; i < 2; i++) {
100  auto waiter = fml::AutoResetWaitableEvent();
101  auto rattle = DeathRattle([&waiter]() { waiter.Signal(); });
102  {
103  UniqueResourceVKT<DeathRattle> resource(context->GetResourceManager(),
104  std::move(rattle));
105  }
106  waiter.Wait();
107  }
108 
109  auto const called = GetMockVulkanFunctions(context->GetDevice());
110  EXPECT_EQ(
111  std::count(called->begin(), called->end(), "vkCreateDescriptorPool"),
112  33u);
113  EXPECT_EQ(std::count(called->begin(), called->end(), "vkResetDescriptorPool"),
114  33u);
115 
116  // Now create 33 more descriptor pools and observe that only one more is
117  // allocated.
118  {
119  std::vector<std::unique_ptr<DescriptorPoolVK>> pools;
120  for (auto i = 0u; i < 33; i++) {
121  auto pool = std::make_unique<DescriptorPoolVK>(context);
122  pool->AllocateDescriptorSets({}, *context);
123  pools.push_back(std::move(pool));
124  }
125  }
126 
127  for (auto i = 0u; i < 2; i++) {
128  auto waiter = fml::AutoResetWaitableEvent();
129  auto rattle = DeathRattle([&waiter]() { waiter.Signal(); });
130  {
131  UniqueResourceVKT<DeathRattle> resource(context->GetResourceManager(),
132  std::move(rattle));
133  }
134  waiter.Wait();
135  }
136 
137  auto const called_twice = GetMockVulkanFunctions(context->GetDevice());
138  // 32 of the descriptor pools were recycled, so only one more is created.
139  EXPECT_EQ(
140  std::count(called->begin(), called->end(), "vkCreateDescriptorPool"),
141  34u);
142 
143  context->Shutdown();
144 }

◆ TEST() [101/370]

impeller::testing::TEST ( DescriptorPoolRecyclerVKTest  ,
ReclaimMakesDescriptorPoolAvailable   
)

Definition at line 47 of file descriptor_pool_vk_unittests.cc.

47  {
48  auto const context = MockVulkanContextBuilder().Build();
49 
50  {
51  // Fetch a pool (which will be created).
52  auto pool = DescriptorPoolVK(context);
53  pool.AllocateDescriptorSets({}, *context);
54  }
55 
56  // There is a chance that the first death rattle item below is destroyed in
57  // the same reclaim cycle as the pool allocation above. These items are placed
58  // into a std::vector and free'd, which may free in reverse order. That would
59  // imply that the death rattle and subsequent waitable event fires before the
60  // pool is reset. To work around this, we can either manually remove items
61  // from the vector or use two death rattles.
62  for (auto i = 0u; i < 2; i++) {
63  // Add something to the resource manager and have it notify us when it's
64  // destroyed. That should give us a non-flaky signal that the pool has been
65  // reclaimed as well.
66  auto waiter = fml::AutoResetWaitableEvent();
67  auto rattle = DeathRattle([&waiter]() { waiter.Signal(); });
68  {
69  UniqueResourceVKT<DeathRattle> resource(context->GetResourceManager(),
70  std::move(rattle));
71  }
72  waiter.Wait();
73  }
74 
75  auto const pool = context->GetDescriptorPoolRecycler()->Get();
76 
77  // Now check that we only ever created one pool.
78  auto const called = GetMockVulkanFunctions(context->GetDevice());
79  EXPECT_EQ(
80  std::count(called->begin(), called->end(), "vkCreateDescriptorPool"), 1u);
81 
82  context->Shutdown();
83 }

◆ TEST() [102/370]

impeller::testing::TEST ( DisplayListTest  ,
CircleBoundsComputation   
)

Definition at line 1789 of file dl_unittests.cc.

1789  {
1790  SkPath path = SkPath().addCircle(0, 0, 5);
1791 
1792  flutter::DlPaint paint;
1793  flutter::DisplayListBuilder builder;
1794 
1795  builder.DrawPath(path, paint);
1796  auto display_list = builder.Build();
1797 
1798  DlDispatcher dispatcher;
1799  display_list->Dispatch(dispatcher);
1800  auto picture = dispatcher.EndRecordingAsPicture();
1801 
1802  std::optional<Rect> coverage =
1803  GetCoverageOfFirstEntity<SolidColorContents>(picture);
1804 
1805  ASSERT_TRUE(coverage.has_value());
1806  ASSERT_EQ(coverage.value_or(Rect::MakeMaximum()),
1807  Rect::MakeLTRB(-5, -5, 5, 5));
1808 }

References impeller::DlDispatcher::EndRecordingAsPicture(), impeller::TRect< Scalar >::MakeLTRB(), and impeller::TRect< Scalar >::MakeMaximum().

◆ TEST() [103/370]

impeller::testing::TEST ( DisplayListTest  ,
RRectBoundsComputation   
)

Definition at line 1766 of file dl_unittests.cc.

1766  {
1767  SkRRect rrect = SkRRect::MakeRectXY(SkRect::MakeLTRB(0, 0, 100, 100), 4, 4);
1768  SkPath path = SkPath().addRRect(rrect);
1769 
1770  flutter::DlPaint paint;
1771  flutter::DisplayListBuilder builder;
1772 
1773  builder.DrawPath(path, paint);
1774  auto display_list = builder.Build();
1775 
1776  DlDispatcher dispatcher;
1777  display_list->Dispatch(dispatcher);
1778  auto picture = dispatcher.EndRecordingAsPicture();
1779 
1780  std::optional<Rect> coverage =
1781  GetCoverageOfFirstEntity<SolidColorContents>(picture);
1782 
1783  // Validate that the RRect coverage is _exactly_ the same as the input rect.
1784  ASSERT_TRUE(coverage.has_value());
1785  ASSERT_EQ(coverage.value_or(Rect::MakeMaximum()),
1786  Rect::MakeLTRB(0, 0, 100, 100));
1787 }

References impeller::DlDispatcher::EndRecordingAsPicture(), impeller::TRect< Scalar >::MakeLTRB(), and impeller::TRect< Scalar >::MakeMaximum().

◆ TEST() [104/370]

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

Definition at line 91 of file geometry_unittests.cc.

91  {
92  auto path = PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 100, 100)).TakePath();
93  auto geometry = Geometry::MakeFillPath(
94  path, /* inner rect */ Rect::MakeLTRB(0, 0, 100, 100));
95  ASSERT_TRUE(geometry->CoversArea({}, Rect::MakeLTRB(0, 0, 100, 100)));
96  ASSERT_FALSE(geometry->CoversArea({}, Rect::MakeLTRB(-1, 0, 100, 100)));
97  ASSERT_TRUE(geometry->CoversArea({}, Rect::MakeLTRB(1, 1, 100, 100)));
98  ASSERT_TRUE(geometry->CoversArea({}, Rect()));
99 }

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

◆ TEST() [105/370]

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

Definition at line 101 of file geometry_unittests.cc.

101  {
102  auto path = PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 100, 100)).TakePath();
103  auto geometry = Geometry::MakeFillPath(path);
104  ASSERT_FALSE(geometry->CoversArea({}, Rect::MakeLTRB(0, 0, 100, 100)));
105  ASSERT_FALSE(geometry->CoversArea({}, Rect::MakeLTRB(-1, 0, 100, 100)));
106  ASSERT_FALSE(geometry->CoversArea({}, Rect::MakeLTRB(1, 1, 100, 100)));
107  ASSERT_FALSE(geometry->CoversArea({}, Rect()));
108 }

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

◆ TEST() [106/370]

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

Definition at line 234 of file geometry_unittests.cc.

234  {
235  GeometryResult result;
236  EXPECT_EQ(result.type, PrimitiveType::kTriangleStrip);
237  EXPECT_EQ(result.transform, Matrix());
238  EXPECT_EQ(result.mode, GeometryResult::Mode::kNormal);
239 }

References impeller::GeometryResult::kNormal, impeller::kTriangleStrip, impeller::GeometryResult::mode, impeller::GeometryResult::transform, and impeller::GeometryResult::type.

◆ TEST() [107/370]

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

Definition at line 110 of file geometry_unittests.cc.

110  {
111  {
112  auto geometry = Geometry::MakeLine({10, 10}, {20, 10}, 2, Cap::kButt);
113  EXPECT_EQ(geometry->GetCoverage({}), Rect::MakeLTRB(10, 9, 20, 11));
114  EXPECT_TRUE(geometry->CoversArea({}, Rect::MakeLTRB(10, 9, 20, 11)));
115  }
116 
117  {
118  auto geometry = Geometry::MakeLine({10, 10}, {20, 10}, 2, Cap::kSquare);
119  EXPECT_EQ(geometry->GetCoverage({}), Rect::MakeLTRB(9, 9, 21, 11));
120  EXPECT_TRUE(geometry->CoversArea({}, Rect::MakeLTRB(9, 9, 21, 11)));
121  }
122 
123  {
124  auto geometry = Geometry::MakeLine({10, 10}, {10, 20}, 2, Cap::kButt);
125  EXPECT_EQ(geometry->GetCoverage({}), Rect::MakeLTRB(9, 10, 11, 20));
126  EXPECT_TRUE(geometry->CoversArea({}, Rect::MakeLTRB(9, 10, 11, 20)));
127  }
128 
129  {
130  auto geometry = Geometry::MakeLine({10, 10}, {10, 20}, 2, Cap::kSquare);
131  EXPECT_EQ(geometry->GetCoverage({}), Rect::MakeLTRB(9, 9, 11, 21));
132  EXPECT_TRUE(geometry->CoversArea({}, Rect::MakeLTRB(9, 9, 11, 21)));
133  }
134 }

References impeller::kButt, impeller::kSquare, impeller::Geometry::MakeLine(), and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST() [108/370]

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

Definition at line 83 of file geometry_unittests.cc.

83  {
84  auto geometry = Geometry::MakeRect(Rect::MakeLTRB(0, 0, 100, 100));
85  ASSERT_TRUE(geometry->CoversArea({}, Rect::MakeLTRB(0, 0, 100, 100)));
86  ASSERT_FALSE(geometry->CoversArea({}, Rect::MakeLTRB(-1, 0, 100, 100)));
87  ASSERT_TRUE(geometry->CoversArea({}, Rect::MakeLTRB(1, 1, 100, 100)));
88  ASSERT_TRUE(geometry->CoversArea({}, Rect()));
89 }

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

◆ TEST() [109/370]

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

Definition at line 136 of file geometry_unittests.cc.

136  {
137  auto geometry =
138  Geometry::MakeRoundRect(Rect::MakeLTRB(0, 0, 100, 100), Size(20, 20));
139  EXPECT_FALSE(geometry->CoversArea({}, Rect::MakeLTRB(15, 15, 85, 85)));
140  EXPECT_TRUE(geometry->CoversArea({}, Rect::MakeLTRB(20, 20, 80, 80)));
141  EXPECT_TRUE(geometry->CoversArea({}, Rect::MakeLTRB(30, 1, 70, 99)));
142  EXPECT_TRUE(geometry->CoversArea({}, Rect::MakeLTRB(1, 30, 99, 70)));
143 }

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

◆ TEST() [110/370]

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

Definition at line 145 of file geometry_unittests.cc.

145  {
146  auto path =
147  PathBuilder().AddLine(Point(100, 100), Point(200, 100)).TakePath();
148  auto points = std::make_unique<std::vector<Point>>();
149  auto polyline =
150  path.CreatePolyline(1.0f, std::move(points),
151  [&points](Path::Polyline::PointBufferPtr reclaimed) {
152  points = std::move(reclaimed);
153  });
154 
155  auto vertices = ImpellerEntityUnitTestAccessor::GenerateSolidStrokeVertices(
156  polyline, 10.0f, 10.0f, Join::kBevel, Cap::kButt, 1.0);
157 
158  std::vector<SolidFillVertexShader::PerVertexData> expected = {
159  {.position = Point(100.0f, 105.0f)}, //
160  {.position = Point(100.0f, 95.0f)}, //
161  {.position = Point(100.0f, 105.0f)}, //
162  {.position = Point(100.0f, 95.0f)}, //
163  {.position = Point(200.0f, 105.0f)}, //
164  {.position = Point(200.0f, 95.0f)}, //
165  {.position = Point(200.0f, 105.0f)}, //
166  {.position = Point(200.0f, 95.0f)}, //
167  };
168 
169  EXPECT_SOLID_VERTICES_NEAR(vertices, expected);
170 
171  {
172  auto uv_vertices =
173  ImpellerEntityUnitTestAccessor::GenerateSolidStrokeVerticesUV(
174  polyline, 10.0f, 10.0f, Join::kBevel, Cap::kButt, 1.0, //
175  Point(50.0f, 40.0f), Size(20.0f, 40.0f), Matrix());
176  // uvx = (x - 50) / 20
177  // uvy = (y - 40) / 40
178  auto uv = [](const Point& p) {
179  return Point((p.x - 50.0f) / 20.0f, //
180  (p.y - 40.0f) / 40.0f);
181  };
182  std::vector<TextureFillVertexShader::PerVertexData> uv_expected;
183  for (size_t i = 0; i < expected.size(); i++) {
184  auto p = expected[i].position;
185  uv_expected.push_back({.position = p, .texture_coords = uv(p)});
186  }
187 
188  EXPECT_TEXTURE_VERTICES_NEAR(uv_vertices, uv_expected);
189  }
190 
191  {
192  auto uv_vertices =
193  ImpellerEntityUnitTestAccessor::GenerateSolidStrokeVerticesUV(
194  polyline, 10.0f, 10.0f, Join::kBevel, Cap::kButt, 1.0, //
195  Point(50.0f, 40.0f), Size(20.0f, 40.0f),
196  Matrix::MakeScale({8.0f, 4.0f, 1.0f}));
197  // uvx = ((x * 8) - 50) / 20
198  // uvy = ((y * 4) - 40) / 40
199  auto uv = [](const Point& p) {
200  return Point(((p.x * 8.0f) - 50.0f) / 20.0f,
201  ((p.y * 4.0f) - 40.0f) / 40.0f);
202  };
203  std::vector<TextureFillVertexShader::PerVertexData> uv_expected;
204  for (size_t i = 0; i < expected.size(); i++) {
205  auto p = expected[i].position;
206  uv_expected.push_back({.position = p, .texture_coords = uv(p)});
207  }
208 
209  EXPECT_TEXTURE_VERTICES_NEAR(uv_vertices, uv_expected);
210  }
211 
212  {
213  auto uv_vertices =
214  ImpellerEntityUnitTestAccessor::GenerateSolidStrokeVerticesUV(
215  polyline, 10.0f, 10.0f, Join::kBevel, Cap::kButt, 1.0, //
216  Point(50.0f, 40.0f), Size(20.0f, 40.0f),
217  Matrix::MakeTranslation({8.0f, 4.0f}));
218  // uvx = ((x + 8) - 50) / 20
219  // uvy = ((y + 4) - 40) / 40
220  auto uv = [](const Point& p) {
221  return Point(((p.x + 8.0f) - 50.0f) / 20.0f,
222  ((p.y + 4.0f) - 40.0f) / 40.0f);
223  };
224  std::vector<TextureFillVertexShader::PerVertexData> uv_expected;
225  for (size_t i = 0; i < expected.size(); i++) {
226  auto p = expected[i].position;
227  uv_expected.push_back({.position = p, .texture_coords = uv(p)});
228  }
229 
230  EXPECT_TEXTURE_VERTICES_NEAR(uv_vertices, uv_expected);
231  }
232 }

References impeller::PathBuilder::AddLine(), EXPECT_SOLID_VERTICES_NEAR, EXPECT_TEXTURE_VERTICES_NEAR, impeller::ImpellerEntityUnitTestAccessor::GenerateSolidStrokeVertices(), impeller::ImpellerEntityUnitTestAccessor::GenerateSolidStrokeVerticesUV(), impeller::kBevel, impeller::kButt, impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), polyline, and impeller::PathBuilder::TakePath().

◆ TEST() [111/370]

impeller::testing::TEST ( EntityPassClipStackTest  ,
AppendAndRestoreClipCoverage   
)

Definition at line 89 of file entity_pass_unittests.cc.

89  {
90  EntityPassClipStack recorder =
91  EntityPassClipStack(Rect::MakeLTRB(0, 0, 100, 100));
92 
93  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 1u);
94 
95  // Push a clip.
96  Entity entity;
97  entity.SetClipDepth(0);
98  EntityPassClipStack::ClipStateResult result = recorder.ApplyClipState(
99  Contents::ClipCoverage{
100  .type = Contents::ClipCoverage::Type::kAppend,
101  .coverage = Rect::MakeLTRB(50, 50, 55, 55),
102  },
103  entity, 0, Point(0, 0));
104  EXPECT_TRUE(result.should_render);
105  EXPECT_TRUE(result.clip_did_change);
106 
107  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 2u);
108  EXPECT_EQ(recorder.GetClipCoverageLayers()[1].coverage,
109  Rect::MakeLTRB(50, 50, 55, 55));
110  EXPECT_EQ(recorder.GetClipCoverageLayers()[1].clip_depth, 1u);
111  EXPECT_EQ(recorder.GetReplayEntities().size(), 1u);
112 
113  // Restore the clip.
114  entity.SetClipDepth(0);
115  recorder.ApplyClipState(
116  Contents::ClipCoverage{
118  .coverage = Rect::MakeLTRB(50, 50, 55, 55),
119  },
120  entity, 0, Point(0, 0));
121 
122  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 1u);
123  EXPECT_EQ(recorder.GetClipCoverageLayers()[0].coverage,
124  Rect::MakeSize(Size::MakeWH(100, 100)));
125  EXPECT_EQ(recorder.GetClipCoverageLayers()[0].clip_depth, 0u);
126  EXPECT_EQ(recorder.GetReplayEntities().size(), 0u);
127 }

References impeller::EntityPassClipStack::ApplyClipState(), impeller::EntityPassClipStack::ClipStateResult::clip_did_change, impeller::EntityPassClipStack::GetClipCoverageLayers(), impeller::EntityPassClipStack::GetReplayEntities(), impeller::Contents::ClipCoverage::kAppend, impeller::Contents::ClipCoverage::kRestore, impeller::TRect< Scalar >::MakeLTRB(), impeller::TRect< Scalar >::MakeSize(), impeller::TSize< Scalar >::MakeWH(), impeller::Entity::SetClipDepth(), impeller::EntityPassClipStack::ClipStateResult::should_render, and impeller::Contents::ClipCoverage::type.

◆ TEST() [112/370]

impeller::testing::TEST ( EntityPassClipStackTest  ,
AppendCoverageNoChange   
)

Definition at line 66 of file entity_pass_unittests.cc.

66  {
67  EntityPassClipStack recorder =
68  EntityPassClipStack(Rect::MakeLTRB(0, 0, 100, 100));
69 
70  EXPECT_EQ(recorder.GetClipCoverageLayers()[0].coverage,
71  Rect::MakeSize(Size::MakeWH(100, 100)));
72  EXPECT_EQ(recorder.GetClipCoverageLayers()[0].clip_depth, 0u);
73 
74  Entity entity;
75  EntityPassClipStack::ClipStateResult result = recorder.ApplyClipState(
76  Contents::ClipCoverage{
77  .type = Contents::ClipCoverage::Type::kNoChange,
78  .coverage = std::nullopt,
79  },
80  entity, 0, Point(0, 0));
81  EXPECT_TRUE(result.should_render);
82  EXPECT_FALSE(result.clip_did_change);
83 
84  EXPECT_EQ(recorder.GetClipCoverageLayers()[0].coverage,
85  Rect::MakeSize(Size::MakeWH(100, 100)));
86  EXPECT_EQ(recorder.GetClipCoverageLayers()[0].clip_depth, 0u);
87 }

References impeller::EntityPassClipStack::ApplyClipState(), impeller::EntityPassClipStack::ClipStateResult::clip_did_change, impeller::EntityPassClipStack::GetClipCoverageLayers(), impeller::Contents::ClipCoverage::kNoChange, impeller::TRect< Scalar >::MakeLTRB(), impeller::TRect< Scalar >::MakeSize(), impeller::TSize< Scalar >::MakeWH(), impeller::EntityPassClipStack::ClipStateResult::should_render, and impeller::Contents::ClipCoverage::type.

◆ TEST() [113/370]

impeller::testing::TEST ( EntityPassClipStackTest  ,
CanAppendNoChange   
)

Definition at line 54 of file entity_pass_unittests.cc.

54  {
55  EntityPassClipStack recorder =
56  EntityPassClipStack(Rect::MakeLTRB(0, 0, 100, 100));
57 
58  EXPECT_TRUE(recorder.GetReplayEntities().empty());
59 
60  Entity entity;
61  recorder.RecordEntity(entity, Contents::ClipCoverage::Type::kNoChange,
62  Rect());
63  EXPECT_TRUE(recorder.GetReplayEntities().empty());
64 }

References impeller::EntityPassClipStack::GetReplayEntities(), impeller::Contents::ClipCoverage::kNoChange, impeller::TRect< Scalar >::MakeLTRB(), and impeller::EntityPassClipStack::RecordEntity().

◆ TEST() [114/370]

impeller::testing::TEST ( EntityPassClipStackTest  ,
CanPopEntitiesSafely   
)

Definition at line 43 of file entity_pass_unittests.cc.

43  {
44  EntityPassClipStack recorder =
45  EntityPassClipStack(Rect::MakeLTRB(0, 0, 100, 100));
46 
47  EXPECT_TRUE(recorder.GetReplayEntities().empty());
48 
49  Entity entity;
50  recorder.RecordEntity(entity, Contents::ClipCoverage::Type::kRestore, Rect());
51  EXPECT_TRUE(recorder.GetReplayEntities().empty());
52 }

References impeller::EntityPassClipStack::GetReplayEntities(), impeller::Contents::ClipCoverage::kRestore, impeller::TRect< Scalar >::MakeLTRB(), and impeller::EntityPassClipStack::RecordEntity().

◆ TEST() [115/370]

impeller::testing::TEST ( EntityPassClipStackTest  ,
CanPushAndPopEntities   
)

Definition at line 13 of file entity_pass_unittests.cc.

13  {
14  EntityPassClipStack recorder =
15  EntityPassClipStack(Rect::MakeLTRB(0, 0, 100, 100));
16 
17  EXPECT_TRUE(recorder.GetReplayEntities().empty());
18 
19  Entity entity;
20  recorder.RecordEntity(entity, Contents::ClipCoverage::Type::kAppend,
21  Rect::MakeLTRB(0, 0, 100, 100));
22  EXPECT_EQ(recorder.GetReplayEntities().size(), 1u);
23 
24  recorder.RecordEntity(entity, Contents::ClipCoverage::Type::kAppend,
25  Rect::MakeLTRB(0, 0, 50, 50));
26  EXPECT_EQ(recorder.GetReplayEntities().size(), 2u);
27  ASSERT_TRUE(recorder.GetReplayEntities()[0].clip_coverage.has_value());
28  ASSERT_TRUE(recorder.GetReplayEntities()[1].clip_coverage.has_value());
29  // NOLINTBEGIN(bugprone-unchecked-optional-access)
30  EXPECT_EQ(recorder.GetReplayEntities()[0].clip_coverage.value(),
31  Rect::MakeLTRB(0, 0, 100, 100));
32  EXPECT_EQ(recorder.GetReplayEntities()[1].clip_coverage.value(),
33  Rect::MakeLTRB(0, 0, 50, 50));
34  // NOLINTEND(bugprone-unchecked-optional-access)
35 
36  recorder.RecordEntity(entity, Contents::ClipCoverage::Type::kRestore, Rect());
37  EXPECT_EQ(recorder.GetReplayEntities().size(), 1u);
38 
39  recorder.RecordEntity(entity, Contents::ClipCoverage::Type::kRestore, Rect());
40  EXPECT_TRUE(recorder.GetReplayEntities().empty());
41 }

References impeller::EntityPassClipStack::GetReplayEntities(), impeller::Contents::ClipCoverage::kAppend, impeller::Contents::ClipCoverage::kRestore, impeller::TRect< Scalar >::MakeLTRB(), and impeller::EntityPassClipStack::RecordEntity().

◆ TEST() [116/370]

impeller::testing::TEST ( EntityPassClipStackTest  ,
ClipAndRestoreWithSubpasses   
)

Definition at line 154 of file entity_pass_unittests.cc.

154  {
155  EntityPassClipStack recorder =
156  EntityPassClipStack(Rect::MakeLTRB(0, 0, 100, 100));
157 
158  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 1u);
159 
160  // Push a clip.
161  Entity entity;
162  entity.SetClipDepth(0u);
163  {
164  EntityPassClipStack::ClipStateResult result = recorder.ApplyClipState(
165  Contents::ClipCoverage{
166  .type = Contents::ClipCoverage::Type::kAppend,
167  .coverage = Rect::MakeLTRB(50, 50, 55, 55),
168  },
169  entity, 0, Point(0, 0));
170  EXPECT_TRUE(result.should_render);
171  EXPECT_TRUE(result.clip_did_change);
172  }
173 
174  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 2u);
175  EXPECT_EQ(recorder.GetClipCoverageLayers()[1].coverage,
176  Rect::MakeLTRB(50, 50, 55, 55));
177  EXPECT_EQ(recorder.GetClipCoverageLayers()[1].clip_depth, 1u);
178  EXPECT_EQ(recorder.GetReplayEntities().size(), 1u);
179 
180  // Begin a subpass.
181  recorder.PushSubpass(Rect::MakeLTRB(50, 50, 55, 55), 1);
182  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 1u);
183  EXPECT_EQ(recorder.GetClipCoverageLayers()[0].coverage,
184  Rect::MakeLTRB(50, 50, 55, 55));
185 
186  entity.SetClipDepth(1);
187  {
188  EntityPassClipStack::ClipStateResult result = recorder.ApplyClipState(
189  Contents::ClipCoverage{
190  .type = Contents::ClipCoverage::Type::kAppend,
191  .coverage = Rect::MakeLTRB(54, 54, 55, 55),
192  },
193  entity, 0, Point(0, 0));
194  EXPECT_TRUE(result.should_render);
195  EXPECT_TRUE(result.clip_did_change);
196  }
197 
198  EXPECT_EQ(recorder.GetClipCoverageLayers()[1].coverage,
199  Rect::MakeLTRB(54, 54, 55, 55));
200 
201  // End subpass.
202  recorder.PopSubpass();
203 
204  EXPECT_EQ(recorder.GetClipCoverageLayers()[1].coverage,
205  Rect::MakeLTRB(50, 50, 55, 55));
206 }

References impeller::EntityPassClipStack::ApplyClipState(), impeller::EntityPassClipStack::ClipStateResult::clip_did_change, impeller::EntityPassClipStack::GetClipCoverageLayers(), impeller::EntityPassClipStack::GetReplayEntities(), impeller::Contents::ClipCoverage::kAppend, impeller::TRect< Scalar >::MakeLTRB(), impeller::EntityPassClipStack::PopSubpass(), impeller::EntityPassClipStack::PushSubpass(), impeller::Entity::SetClipDepth(), impeller::EntityPassClipStack::ClipStateResult::should_render, and impeller::Contents::ClipCoverage::type.

◆ TEST() [117/370]

impeller::testing::TEST ( EntityPassClipStackTest  ,
UnbalancedRestore   
)

Definition at line 129 of file entity_pass_unittests.cc.

129  {
130  EntityPassClipStack recorder =
131  EntityPassClipStack(Rect::MakeLTRB(0, 0, 100, 100));
132 
133  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 1u);
134 
135  // Restore the clip.
136  Entity entity;
137  entity.SetClipDepth(0);
138  EntityPassClipStack::ClipStateResult result = recorder.ApplyClipState(
139  Contents::ClipCoverage{
141  .coverage = Rect::MakeLTRB(50, 50, 55, 55),
142  },
143  entity, 0, Point(0, 0));
144  EXPECT_FALSE(result.should_render);
145  EXPECT_FALSE(result.clip_did_change);
146 
147  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 1u);
148  EXPECT_EQ(recorder.GetClipCoverageLayers()[0].coverage,
149  Rect::MakeSize(Size::MakeWH(100, 100)));
150  EXPECT_EQ(recorder.GetClipCoverageLayers()[0].clip_depth, 0u);
151  EXPECT_EQ(recorder.GetReplayEntities().size(), 0u);
152 }

References impeller::EntityPassClipStack::ApplyClipState(), impeller::EntityPassClipStack::ClipStateResult::clip_did_change, impeller::EntityPassClipStack::GetClipCoverageLayers(), impeller::EntityPassClipStack::GetReplayEntities(), impeller::Contents::ClipCoverage::kRestore, impeller::TRect< Scalar >::MakeLTRB(), impeller::TRect< Scalar >::MakeSize(), impeller::TSize< Scalar >::MakeWH(), impeller::Entity::SetClipDepth(), impeller::EntityPassClipStack::ClipStateResult::should_render, and impeller::Contents::ClipCoverage::type.

◆ TEST() [118/370]

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

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

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

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

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

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

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

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.SetTransform(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::SetTransform().

◆ TEST() [126/370]

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

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

impeller::testing::TEST ( GaussianBlurFilterContentsTest  ,
CalculateSigmaForBlurRadius   
)

Definition at line 429 of file gaussian_blur_filter_contents_unittests.cc.

429  {
430  Scalar sigma = 1.0;
431  Scalar radius = GaussianBlurFilterContents::CalculateBlurRadius(
432  GaussianBlurFilterContents::ScaleSigma(sigma));
433  fml::StatusOr<Scalar> derived_sigma =
434  CalculateSigmaForBlurRadius(radius, Matrix());
435  ASSERT_TRUE(derived_sigma.ok());
436  EXPECT_NEAR(sigma, derived_sigma.value(), 0.01f);
437 }

References impeller::GaussianBlurFilterContents::CalculateBlurRadius(), and impeller::GaussianBlurFilterContents::ScaleSigma().

◆ TEST() [129/370]

impeller::testing::TEST ( GaussianBlurFilterContentsTest  ,
CalculateSigmaValues   
)

Definition at line 200 of file gaussian_blur_filter_contents_unittests.cc.

200  {
201  EXPECT_EQ(GaussianBlurFilterContents::CalculateScale(1.0f), 1);
202  EXPECT_EQ(GaussianBlurFilterContents::CalculateScale(2.0f), 1);
203  EXPECT_EQ(GaussianBlurFilterContents::CalculateScale(3.0f), 1);
204  EXPECT_EQ(GaussianBlurFilterContents::CalculateScale(4.0f), 1);
205  EXPECT_EQ(GaussianBlurFilterContents::CalculateScale(16.0f), 0.25);
206  // Hang on to 1/8 as long as possible.
207  EXPECT_EQ(GaussianBlurFilterContents::CalculateScale(95.0f), 0.125);
208  EXPECT_EQ(GaussianBlurFilterContents::CalculateScale(96.0f), 0.0625);
209  // Downsample clamped to 1/16th.
210  EXPECT_EQ(GaussianBlurFilterContents::CalculateScale(1024.0f), 0.0625);
211 }

References impeller::GaussianBlurFilterContents::CalculateScale().

◆ TEST() [130/370]

impeller::testing::TEST ( GaussianBlurFilterContentsTest  ,
Coefficients   
)

Definition at line 439 of file gaussian_blur_filter_contents_unittests.cc.

439  {
440  BlurParameters parameters = {.blur_uv_offset = Point(1, 0),
441  .blur_sigma = 1,
442  .blur_radius = 5,
443  .step_size = 1};
444  KernelPipeline::FragmentShader::KernelSamples samples =
445  GenerateBlurInfo(parameters);
446  EXPECT_EQ(samples.sample_count, 9);
447 
448  // Coefficients should add up to 1.
449  Scalar tally = 0;
450  for (int i = 0; i < samples.sample_count; ++i) {
451  tally += samples.samples[i].coefficient;
452  }
453  EXPECT_FLOAT_EQ(tally, 1.0f);
454 
455  // Verify the shape of the curve.
456  for (int i = 0; i < 4; ++i) {
457  EXPECT_FLOAT_EQ(samples.samples[i].coefficient,
458  samples.samples[8 - i].coefficient);
459  EXPECT_TRUE(samples.samples[i + 1].coefficient >
460  samples.samples[i].coefficient);
461  }
462 }

References impeller::BlurParameters::blur_uv_offset, and impeller::GenerateBlurInfo().

◆ TEST() [131/370]

impeller::testing::TEST ( GaussianBlurFilterContentsTest  ,
CoverageEmpty   
)

Definition at line 96 of file gaussian_blur_filter_contents_unittests.cc.

96  {
97  GaussianBlurFilterContents contents(
98  /*sigma_x=*/0.0, /*sigma_y=*/0.0, Entity::TileMode::kDecal,
99  FilterContents::BlurStyle::kNormal, /*mask_geometry=*/nullptr);
100  FilterInput::Vector inputs = {};
101  Entity entity;
102  std::optional<Rect> coverage =
103  contents.GetFilterCoverage(inputs, entity, /*effect_transform=*/Matrix());
104  ASSERT_FALSE(coverage.has_value());
105 }

References impeller::GaussianBlurFilterContents::GetFilterCoverage(), impeller::Entity::kDecal, and impeller::FilterContents::kNormal.

◆ TEST() [132/370]

impeller::testing::TEST ( GaussianBlurFilterContentsTest  ,
CoverageSimple   
)

Definition at line 107 of file gaussian_blur_filter_contents_unittests.cc.

107  {
108  GaussianBlurFilterContents contents(
109  /*sigma_x=*/0.0, /*sigma_y=*/0.0, Entity::TileMode::kDecal,
110  FilterContents::BlurStyle::kNormal, /*mask_geometry=*/nullptr);
111  FilterInput::Vector inputs = {
112  FilterInput::Make(Rect::MakeLTRB(10, 10, 110, 110))};
113  Entity entity;
114  std::optional<Rect> coverage =
115  contents.GetFilterCoverage(inputs, entity, /*effect_transform=*/Matrix());
116 
117  ASSERT_EQ(coverage, Rect::MakeLTRB(10, 10, 110, 110));
118 }

References impeller::GaussianBlurFilterContents::GetFilterCoverage(), impeller::Entity::kDecal, impeller::FilterContents::kNormal, impeller::FilterInput::Make(), and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST() [133/370]

impeller::testing::TEST ( GaussianBlurFilterContentsTest  ,
CoverageWithSigma   
)

Definition at line 120 of file gaussian_blur_filter_contents_unittests.cc.

120  {
121  fml::StatusOr<Scalar> sigma_radius_1 =
122  CalculateSigmaForBlurRadius(1.0, Matrix());
123  ASSERT_TRUE(sigma_radius_1.ok());
124  GaussianBlurFilterContents contents(
125  /*sigma_x=*/sigma_radius_1.value(),
126  /*sigma_y=*/sigma_radius_1.value(), Entity::TileMode::kDecal,
127  FilterContents::BlurStyle::kNormal, /*mask_geometry=*/nullptr);
128  FilterInput::Vector inputs = {
129  FilterInput::Make(Rect::MakeLTRB(100, 100, 200, 200))};
130  Entity entity;
131  std::optional<Rect> coverage =
132  contents.GetFilterCoverage(inputs, entity, /*effect_transform=*/Matrix());
133 
134  EXPECT_TRUE(coverage.has_value());
135  if (coverage.has_value()) {
136  EXPECT_RECT_NEAR(coverage.value(), Rect::MakeLTRB(99, 99, 201, 201));
137  }
138 }

References EXPECT_RECT_NEAR, impeller::GaussianBlurFilterContents::GetFilterCoverage(), impeller::Entity::kDecal, impeller::FilterContents::kNormal, impeller::FilterInput::Make(), and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST() [134/370]

impeller::testing::TEST ( GaussianBlurFilterContentsTest  ,
Create   
)

Definition at line 88 of file gaussian_blur_filter_contents_unittests.cc.

88  {
89  GaussianBlurFilterContents contents(
90  /*sigma_x=*/0.0, /*sigma_y=*/0.0, Entity::TileMode::kDecal,
91  FilterContents::BlurStyle::kNormal, /*mask_geometry=*/nullptr);
92  EXPECT_EQ(contents.GetSigmaX(), 0.0);
93  EXPECT_EQ(contents.GetSigmaY(), 0.0);
94 }

References impeller::GaussianBlurFilterContents::GetSigmaX(), impeller::GaussianBlurFilterContents::GetSigmaY(), impeller::Entity::kDecal, and impeller::FilterContents::kNormal.

◆ TEST() [135/370]

impeller::testing::TEST ( GaussianBlurFilterContentsTest  ,
FilterSourceCoverage   
)

Definition at line 183 of file gaussian_blur_filter_contents_unittests.cc.

183  {
184  fml::StatusOr<Scalar> sigma_radius_1 =
185  CalculateSigmaForBlurRadius(1.0, Matrix());
186  ASSERT_TRUE(sigma_radius_1.ok());
187  auto contents = std::make_unique<GaussianBlurFilterContents>(
188  sigma_radius_1.value(), sigma_radius_1.value(), Entity::TileMode::kDecal,
189  FilterContents::BlurStyle::kNormal, /*mask_geometry=*/nullptr);
190  std::optional<Rect> coverage = contents->GetFilterSourceCoverage(
191  /*effect_transform=*/Matrix::MakeScale({2.0, 2.0, 1.0}),
192  /*output_limit=*/Rect::MakeLTRB(100, 100, 200, 200));
193  EXPECT_TRUE(coverage.has_value());
194  if (coverage.has_value()) {
195  EXPECT_RECT_NEAR(coverage.value(),
196  Rect::MakeLTRB(100 - 2, 100 - 2, 200 + 2, 200 + 2));
197  }
198 }

References EXPECT_RECT_NEAR, impeller::Entity::kDecal, impeller::FilterContents::kNormal, impeller::TRect< Scalar >::MakeLTRB(), and impeller::Matrix::MakeScale().

◆ TEST() [136/370]

impeller::testing::TEST ( GaussianBlurFilterContentsTest  ,
LerpHackKernelSamplesComplex   
)

Definition at line 542 of file gaussian_blur_filter_contents_unittests.cc.

542  {
543  Scalar sigma = 10.0f;
544  int32_t blur_radius = static_cast<int32_t>(
545  std::ceil(GaussianBlurFilterContents::CalculateBlurRadius(sigma)));
546  BlurParameters parameters = {.blur_uv_offset = Point(1, 0),
547  .blur_sigma = sigma,
548  .blur_radius = blur_radius,
549  .step_size = 1};
550  KernelPipeline::FragmentShader::KernelSamples kernel_samples =
551  GenerateBlurInfo(parameters);
552  EXPECT_EQ(kernel_samples.sample_count, 33);
553  KernelPipeline::FragmentShader::KernelSamples fast_kernel_samples =
554  LerpHackKernelSamples(kernel_samples);
555  EXPECT_EQ(fast_kernel_samples.sample_count, 17);
556  float data[33];
557  srand(0);
558  for (int i = 0; i < 33; i++) {
559  data[i] = 255.0 * static_cast<double>(IMPELLER_RAND()) / RAND_MAX;
560  }
561 
562  auto sampler = [data](Point point) -> Scalar {
563  FML_CHECK(point.y == 0.0f);
564  FML_CHECK(point.x >= -16);
565  FML_CHECK(point.x <= 16);
566  Scalar fint_part;
567  Scalar fract = fabsf(modf(point.x, &fint_part));
568  if (fract == 0) {
569  int32_t int_part = static_cast<int32_t>(fint_part) + 16;
570  return data[int_part];
571  } else {
572  int32_t left = static_cast<int32_t>(floor(point.x)) + 16;
573  int32_t right = static_cast<int32_t>(ceil(point.x)) + 16;
574  if (point.x < 0) {
575  return fract * data[left] + (1.0 - fract) * data[right];
576  } else {
577  return (1.0 - fract) * data[left] + fract * data[right];
578  }
579  }
580  };
581 
582  Scalar output = 0.0;
583  for (int i = 0; i < kernel_samples.sample_count; ++i) {
584  auto sample = kernel_samples.samples[i];
585  output += sample.coefficient * sampler(sample.uv_offset);
586  }
587 
588  Scalar fast_output = 0.0;
589  for (int i = 0; i < fast_kernel_samples.sample_count; ++i) {
590  auto sample = fast_kernel_samples.samples[i];
591  fast_output += sample.coefficient * sampler(sample.uv_offset);
592  }
593 
594  EXPECT_NEAR(output, fast_output, 0.1);
595 }

References impeller::BlurParameters::blur_uv_offset, impeller::GaussianBlurFilterContents::CalculateBlurRadius(), impeller::GenerateBlurInfo(), IMPELLER_RAND, and impeller::LerpHackKernelSamples().

◆ TEST() [137/370]

impeller::testing::TEST ( GaussianBlurFilterContentsTest  ,
LerpHackKernelSamplesSimple   
)

Definition at line 464 of file gaussian_blur_filter_contents_unittests.cc.

464  {
465  KernelPipeline::FragmentShader::KernelSamples kernel_samples = {
466  .sample_count = 5,
467  .samples =
468  {
469  {
470  .uv_offset = Vector2(-2, 0),
471  .coefficient = 0.1f,
472  },
473  {
474  .uv_offset = Vector2(-1, 0),
475  .coefficient = 0.2f,
476  },
477  {
478  .uv_offset = Vector2(0, 0),
479  .coefficient = 0.4f,
480  },
481  {
482  .uv_offset = Vector2(1, 0),
483  .coefficient = 0.2f,
484  },
485  {
486  .uv_offset = Vector2(2, 0),
487  .coefficient = 0.1f,
488  },
489  },
490  };
491 
492  KernelPipeline::FragmentShader::KernelSamples fast_kernel_samples =
493  LerpHackKernelSamples(kernel_samples);
494  EXPECT_EQ(fast_kernel_samples.sample_count, 3);
495 
496  KernelPipeline::FragmentShader::KernelSample* samples =
497  kernel_samples.samples;
498  KernelPipeline::FragmentShader::KernelSample* fast_samples =
499  fast_kernel_samples.samples;
500 
501  //////////////////////////////////////////////////////////////////////////////
502  // Check output kernel.
503 
504  EXPECT_FLOAT_EQ(fast_samples[0].uv_offset.x, -1.3333333);
505  EXPECT_FLOAT_EQ(fast_samples[0].uv_offset.y, 0);
506  EXPECT_FLOAT_EQ(fast_samples[0].coefficient, 0.3);
507  EXPECT_FLOAT_EQ(fast_samples[1].uv_offset.x, 0);
508  EXPECT_FLOAT_EQ(fast_samples[1].uv_offset.y, 0);
509  EXPECT_FLOAT_EQ(fast_samples[1].coefficient, 0.4);
510  EXPECT_FLOAT_EQ(fast_samples[2].uv_offset.x, 1.3333333);
511  EXPECT_FLOAT_EQ(fast_samples[2].uv_offset.y, 0);
512  EXPECT_FLOAT_EQ(fast_samples[2].coefficient, 0.3);
513 
514  //////////////////////////////////////////////////////////////////////////////
515  // Check output of fast kernel versus original kernel.
516 
517  Scalar data[5] = {0.25, 0.5, 0.5, 1.0, 0.2};
518  Scalar original_output =
519  samples[0].coefficient * data[0] + samples[1].coefficient * data[1] +
520  samples[2].coefficient * data[2] + samples[3].coefficient * data[3] +
521  samples[4].coefficient * data[4];
522 
523  auto lerp = [](const Point& point, Scalar left, Scalar right) {
524  Scalar int_part;
525  Scalar fract = fabsf(modf(point.x, &int_part));
526  if (point.x < 0) {
527  return left * fract + right * (1.0 - fract);
528  } else {
529  return left * (1.0 - fract) + right * fract;
530  }
531  };
532  Scalar fast_output =
533  /*1st*/ lerp(fast_samples[0].uv_offset, data[0], data[1]) *
534  fast_samples[0].coefficient +
535  /*2nd*/ data[2] * fast_samples[1].coefficient +
536  /*3rd*/ lerp(fast_samples[2].uv_offset, data[3], data[4]) *
537  fast_samples[2].coefficient;
538 
539  EXPECT_NEAR(original_output, fast_output, 0.01);
540 }

References impeller::LerpHackKernelSamples(), and impeller::TPoint< T >::x.

◆ TEST() [138/370]

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

Definition at line 1603 of file geometry_unittests.cc.

1603  {
1604  using BlendT = std::underlying_type_t<BlendMode>;
1605  for (BlendT i = 0; i <= static_cast<BlendT>(BlendMode::kLast); i++) {
1606  auto mode = static_cast<BlendMode>(i);
1607  auto result = BlendModeToString(mode);
1609  }
1610 }

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

◆ TEST() [139/370]

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

Definition at line 1612 of file geometry_unittests.cc.

1612  {
1613  {
1614  auto deg = Degrees{90.0};
1615  Radians rad = deg;
1616  ASSERT_FLOAT_EQ(rad.radians, kPiOver2);
1617  }
1618 }

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

◆ TEST() [140/370]

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

Definition at line 616 of file geometry_unittests.cc.

616  {
617  {
618  Point p1(1.0, 2.0);
619  IPoint p2 = static_cast<IPoint>(p1);
620  ASSERT_EQ(p2.x, 1u);
621  ASSERT_EQ(p2.y, 2u);
622  }
623 
624  {
625  Size s1(1.0, 2.0);
626  ISize s2 = static_cast<ISize>(s1);
627  ASSERT_EQ(s2.width, 1u);
628  ASSERT_EQ(s2.height, 2u);
629  }
630 
631  {
632  Size s1(1.0, 2.0);
633  Point p1 = static_cast<Point>(s1);
634  ASSERT_EQ(p1.x, 1u);
635  ASSERT_EQ(p1.y, 2u);
636  }
637 }

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

◆ TEST() [141/370]

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

Definition at line 603 of file geometry_unittests.cc.

603  {
604  ASSERT_EQ((Size{128, 128}.MipCount()), 7u);
605  ASSERT_EQ((Size{128, 256}.MipCount()), 8u);
606  ASSERT_EQ((Size{128, 130}.MipCount()), 8u);
607  ASSERT_EQ((Size{128, 257}.MipCount()), 9u);
608  ASSERT_EQ((Size{257, 128}.MipCount()), 9u);
609  ASSERT_EQ((Size{128, 0}.MipCount()), 1u);
610  ASSERT_EQ((Size{128, -25}.MipCount()), 1u);
611  ASSERT_EQ((Size{-128, 25}.MipCount()), 1u);
612  ASSERT_EQ((Size{1, 1}.MipCount()), 1u);
613  ASSERT_EQ((Size{0, 0}.MipCount()), 1u);
614 }

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

◆ TEST() [142/370]

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

Definition at line 639 of file geometry_unittests.cc.

639  {
640  {
641  IPoint p1(1, 2);
642  IPoint p2 = p1 + IPoint(1, 2);
643  ASSERT_EQ(p2.x, 2u);
644  ASSERT_EQ(p2.y, 4u);
645  }
646 
647  {
648  IPoint p1(3, 6);
649  IPoint p2 = p1 - IPoint(1, 2);
650  ASSERT_EQ(p2.x, 2u);
651  ASSERT_EQ(p2.y, 4u);
652  }
653 
654  {
655  IPoint p1(1, 2);
656  IPoint p2 = p1 * IPoint(2, 3);
657  ASSERT_EQ(p2.x, 2u);
658  ASSERT_EQ(p2.y, 6u);
659  }
660 
661  {
662  IPoint p1(2, 6);
663  IPoint p2 = p1 / IPoint(2, 3);
664  ASSERT_EQ(p2.x, 1u);
665  ASSERT_EQ(p2.y, 2u);
666  }
667 }

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

◆ TEST() [143/370]

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

Definition at line 669 of file geometry_unittests.cc.

669  {
670  // LHS
671  {
672  IPoint p1(1, 2);
673  IPoint p2 = p1 * 2.0f;
674  ASSERT_EQ(p2.x, 2u);
675  ASSERT_EQ(p2.y, 4u);
676  }
677 
678  {
679  IPoint p1(2, 6);
680  IPoint p2 = p1 / 2.0f;
681  ASSERT_EQ(p2.x, 1u);
682  ASSERT_EQ(p2.y, 3u);
683  }
684 
685  // RHS
686  {
687  IPoint p1(1, 2);
688  IPoint p2 = 2.0f * p1;
689  ASSERT_EQ(p2.x, 2u);
690  ASSERT_EQ(p2.y, 4u);
691  }
692 
693  {
694  IPoint p1(2, 6);
695  IPoint p2 = 12.0f / p1;
696  ASSERT_EQ(p2.x, 6u);
697  ASSERT_EQ(p2.y, 2u);
698  }
699 }

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

◆ TEST() [144/370]

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

Definition at line 1173 of file geometry_unittests.cc.

1173  {
1174  {
1175  Vector3 p1(1, 2, 3);
1176  Vector3 p2 = p1 + Vector3(1, 2, 3);
1177  ASSERT_EQ(p2.x, 2u);
1178  ASSERT_EQ(p2.y, 4u);
1179  ASSERT_EQ(p2.z, 6u);
1180  }
1181 
1182  {
1183  Vector3 p1(3, 6, 9);
1184  Vector3 p2 = p1 - Vector3(1, 2, 3);
1185  ASSERT_EQ(p2.x, 2u);
1186  ASSERT_EQ(p2.y, 4u);
1187  ASSERT_EQ(p2.z, 6u);
1188  }
1189 
1190  {
1191  Vector3 p1(1, 2, 3);
1192  Vector3 p2 = p1 * Vector3(2, 3, 4);
1193  ASSERT_EQ(p2.x, 2u);
1194  ASSERT_EQ(p2.y, 6u);
1195  ASSERT_EQ(p2.z, 12u);
1196  }
1197 
1198  {
1199  Vector3 p1(2, 6, 12);
1200  Vector3 p2 = p1 / Vector3(2, 3, 4);
1201  ASSERT_EQ(p2.x, 1u);
1202  ASSERT_EQ(p2.y, 2u);
1203  ASSERT_EQ(p2.z, 3u);
1204  }
1205 }

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

◆ TEST() [145/370]

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

Definition at line 1207 of file geometry_unittests.cc.

1207  {
1208  // LHS
1209  {
1210  Vector3 p1(1, 2, 3);
1211  Vector3 p2 = p1 + 2.0f;
1212  ASSERT_EQ(p2.x, 3);
1213  ASSERT_EQ(p2.y, 4);
1214  ASSERT_EQ(p2.z, 5);
1215  }
1216 
1217  {
1218  Vector3 p1(1, 2, 3);
1219  Vector3 p2 = p1 - 2.0f;
1220  ASSERT_EQ(p2.x, -1);
1221  ASSERT_EQ(p2.y, 0);
1222  ASSERT_EQ(p2.z, 1);
1223  }
1224 
1225  {
1226  Vector3 p1(1, 2, 3);
1227  Vector3 p2 = p1 * 2.0f;
1228  ASSERT_EQ(p2.x, 2);
1229  ASSERT_EQ(p2.y, 4);
1230  ASSERT_EQ(p2.z, 6);
1231  }
1232 
1233  {
1234  Vector3 p1(2, 6, 12);
1235  Vector3 p2 = p1 / 2.0f;
1236  ASSERT_EQ(p2.x, 1);
1237  ASSERT_EQ(p2.y, 3);
1238  ASSERT_EQ(p2.z, 6);
1239  }
1240 
1241  // RHS
1242  {
1243  Vector3 p1(1, 2, 3);
1244  Vector3 p2 = 2.0f + p1;
1245  ASSERT_EQ(p2.x, 3);
1246  ASSERT_EQ(p2.y, 4);
1247  ASSERT_EQ(p2.z, 5);
1248  }
1249 
1250  {
1251  Vector3 p1(1, 2, 3);
1252  Vector3 p2 = 2.0f - p1;
1253  ASSERT_EQ(p2.x, 1);
1254  ASSERT_EQ(p2.y, 0);
1255  ASSERT_EQ(p2.z, -1);
1256  }
1257 
1258  {
1259  Vector3 p1(1, 2, 3);
1260  Vector3 p2 = 2.0f * p1;
1261  ASSERT_EQ(p2.x, 2);
1262  ASSERT_EQ(p2.y, 4);
1263  ASSERT_EQ(p2.z, 6);
1264  }
1265 
1266  {
1267  Vector3 p1(2, 6, 12);
1268  Vector3 p2 = 12.0f / p1;
1269  ASSERT_EQ(p2.x, 6);
1270  ASSERT_EQ(p2.y, 2);
1271  ASSERT_EQ(p2.z, 1);
1272  }
1273 }

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

◆ TEST() [146/370]

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

Definition at line 821 of file geometry_unittests.cc.

821  {
822  // Point on RHS
823  {
824  IPoint p(1, 2);
825  p += IPoint(1, 2);
826  ASSERT_EQ(p.x, 2u);
827  ASSERT_EQ(p.y, 4u);
828  }
829 
830  {
831  IPoint p(3, 6);
832  p -= IPoint(1, 2);
833  ASSERT_EQ(p.x, 2u);
834  ASSERT_EQ(p.y, 4u);
835  }
836 
837  {
838  IPoint p(1, 2);
839  p *= IPoint(2, 3);
840  ASSERT_EQ(p.x, 2u);
841  ASSERT_EQ(p.y, 6u);
842  }
843 
844  {
845  IPoint p(2, 6);
846  p /= IPoint(2, 3);
847  ASSERT_EQ(p.x, 1u);
848  ASSERT_EQ(p.y, 2u);
849  }
850 
851  // Size on RHS
852  {
853  IPoint p(1, 2);
854  p += ISize(1, 2);
855  ASSERT_EQ(p.x, 2u);
856  ASSERT_EQ(p.y, 4u);
857  }
858 
859  {
860  IPoint p(3, 6);
861  p -= ISize(1, 2);
862  ASSERT_EQ(p.x, 2u);
863  ASSERT_EQ(p.y, 4u);
864  }
865 
866  {
867  IPoint p(1, 2);
868  p *= ISize(2, 3);
869  ASSERT_EQ(p.x, 2u);
870  ASSERT_EQ(p.y, 6u);
871  }
872 
873  {
874  IPoint p(2, 6);
875  p /= ISize(2, 3);
876  ASSERT_EQ(p.x, 1u);
877  ASSERT_EQ(p.y, 2u);
878  }
879 
880  // Arithmetic type on RHS
881  {
882  IPoint p(1, 2);
883  p *= 3;
884  ASSERT_EQ(p.x, 3u);
885  ASSERT_EQ(p.y, 6u);
886  }
887 
888  {
889  IPoint p(3, 6);
890  p /= 3;
891  ASSERT_EQ(p.x, 1u);
892  ASSERT_EQ(p.y, 2u);
893  }
894 }

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

◆ TEST() [147/370]

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

Definition at line 1123 of file geometry_unittests.cc.

1123  {
1124  {
1125  Vector3 p(1, 2, 4);
1126  p += Vector3(1, 2, 4);
1127  ASSERT_EQ(p.x, 2u);
1128  ASSERT_EQ(p.y, 4u);
1129  ASSERT_EQ(p.z, 8u);
1130  }
1131 
1132  {
1133  Vector3 p(3, 6, 8);
1134  p -= Vector3(1, 2, 3);
1135  ASSERT_EQ(p.x, 2u);
1136  ASSERT_EQ(p.y, 4u);
1137  ASSERT_EQ(p.z, 5u);
1138  }
1139 
1140  {
1141  Vector3 p(1, 2, 3);
1142  p *= Vector3(2, 3, 4);
1143  ASSERT_EQ(p.x, 2u);
1144  ASSERT_EQ(p.y, 6u);
1145  ASSERT_EQ(p.z, 12u);
1146  }
1147 
1148  {
1149  Vector3 p(1, 2, 3);
1150  p *= 2;
1151  ASSERT_EQ(p.x, 2u);
1152  ASSERT_EQ(p.y, 4u);
1153  ASSERT_EQ(p.z, 6u);
1154  }
1155 
1156  {
1157  Vector3 p(2, 6, 12);
1158  p /= Vector3(2, 3, 4);
1159  ASSERT_EQ(p.x, 1u);
1160  ASSERT_EQ(p.y, 2u);
1161  ASSERT_EQ(p.z, 3u);
1162  }
1163 
1164  {
1165  Vector3 p(2, 6, 12);
1166  p /= 2;
1167  ASSERT_EQ(p.x, 1u);
1168  ASSERT_EQ(p.y, 3u);
1169  ASSERT_EQ(p.z, 6u);
1170  }
1171 }

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

◆ TEST() [148/370]

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

Definition at line 1380 of file geometry_unittests.cc.

1380  {
1381  {
1382  ColorMatrix color_matrix = {
1383  1, 1, 1, 1, 1, //
1384  1, 1, 1, 1, 1, //
1385  1, 1, 1, 1, 1, //
1386  1, 1, 1, 1, 1, //
1387  };
1388  auto result = Color::White().ApplyColorMatrix(color_matrix);
1389  auto expected = Color(1, 1, 1, 1);
1390  ASSERT_COLOR_NEAR(result, expected);
1391  }
1392 
1393  {
1394  ColorMatrix color_matrix = {
1395  0.1, 0, 0, 0, 0.01, //
1396  0, 0.2, 0, 0, 0.02, //
1397  0, 0, 0.3, 0, 0.03, //
1398  0, 0, 0, 0.4, 0.04, //
1399  };
1400  auto result = Color::White().ApplyColorMatrix(color_matrix);
1401  auto expected = Color(0.11, 0.22, 0.33, 0.44);
1402  ASSERT_COLOR_NEAR(result, expected);
1403  }
1404 }

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

◆ TEST() [149/370]

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

Definition at line 1584 of file geometry_unittests.cc.

1584  {
1585  using BlendT = std::underlying_type_t<BlendMode>;
1586  Color dst = ColorBlendTestData::kDestinationColor;
1587  for (size_t source_i = 0;
1588  source_i < sizeof(ColorBlendTestData::kSourceColors) / sizeof(Color);
1589  source_i++) {
1590  Color src = ColorBlendTestData::kSourceColors[source_i];
1591 
1592  size_t blend_i;
1593  Color expected;
1595  }
1596 }

References _BLEND_MODE_RESULT_CHECK, IMPELLER_FOR_EACH_BLEND_MODE, impeller::testing::ColorBlendTestData::kDestinationColor, and impeller::testing::ColorBlendTestData::kSourceColors.

◆ TEST() [150/370]

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

Definition at line 1340 of file geometry_unittests.cc.

1340  {
1341  {
1342  Color result = Color(0.5, 0.5, 0.5, 0.5).Clamp01();
1343  Color expected = Color(0.5, 0.5, 0.5, 0.5);
1344  ASSERT_COLOR_NEAR(result, expected);
1345  }
1346 
1347  {
1348  Color result = Color(-1, -1, -1, -1).Clamp01();
1349  Color expected = Color(0, 0, 0, 0);
1350  ASSERT_COLOR_NEAR(result, expected);
1351  }
1352 
1353  {
1354  Color result = Color(2, 2, 2, 2).Clamp01();
1355  Color expected = Color(1, 1, 1, 1);
1356  ASSERT_COLOR_NEAR(result, expected);
1357  }
1358 }

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

◆ TEST() [151/370]

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

Definition at line 1318 of file geometry_unittests.cc.

1318  {
1319  {
1320  Color a(0.0, 0.0, 0.0, 0.0);
1321  Color b(1.0, 1.0, 1.0, 1.0);
1322 
1323  ASSERT_COLOR_NEAR(Color::Lerp(a, b, 0.5), Color(0.5, 0.5, 0.5, 0.5));
1324  ASSERT_COLOR_NEAR(Color::Lerp(a, b, 0.0), a);
1325  ASSERT_COLOR_NEAR(Color::Lerp(a, b, 1.0), b);
1326  ASSERT_COLOR_NEAR(Color::Lerp(a, b, 0.2), Color(0.2, 0.2, 0.2, 0.2));
1327  }
1328 
1329  {
1330  Color a(0.2, 0.4, 1.0, 0.5);
1331  Color b(0.4, 1.0, 0.2, 0.3);
1332 
1333  ASSERT_COLOR_NEAR(Color::Lerp(a, b, 0.5), Color(0.3, 0.7, 0.6, 0.4));
1334  ASSERT_COLOR_NEAR(Color::Lerp(a, b, 0.0), a);
1335  ASSERT_COLOR_NEAR(Color::Lerp(a, b, 1.0), b);
1336  ASSERT_COLOR_NEAR(Color::Lerp(a, b, 0.2), Color(0.24, 0.52, 0.84, 0.46));
1337  }
1338 }

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

◆ TEST() [152/370]

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

Definition at line 1406 of file geometry_unittests.cc.

1406  {
1407  {
1408  auto result = Color::White().LinearToSRGB();
1409  auto expected = Color(1, 1, 1, 1);
1410  ASSERT_COLOR_NEAR(result, expected);
1411  }
1412 
1413  {
1414  auto result = Color::BlackTransparent().LinearToSRGB();
1415  auto expected = Color(0, 0, 0, 0);
1416  ASSERT_COLOR_NEAR(result, expected);
1417  }
1418 
1419  {
1420  auto result = Color(0.2, 0.4, 0.6, 0.8).LinearToSRGB();
1421  auto expected = Color(0.484529, 0.665185, 0.797738, 0.8);
1422  ASSERT_COLOR_NEAR(result, expected);
1423  }
1424 }

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

◆ TEST() [153/370]

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

Definition at line 1360 of file geometry_unittests.cc.

1360  {
1361  {
1362  Color a = Color::MakeRGBA8(0, 0, 0, 0);
1363  Color b = Color::BlackTransparent();
1364  ASSERT_COLOR_NEAR(a, b);
1365  }
1366 
1367  {
1368  Color a = Color::MakeRGBA8(255, 255, 255, 255);
1369  Color b = Color::White();
1370  ASSERT_COLOR_NEAR(a, b);
1371  }
1372 
1373  {
1374  Color a = Color::MakeRGBA8(63, 127, 191, 127);
1375  Color b(0.247059, 0.498039, 0.74902, 0.498039);
1376  ASSERT_COLOR_NEAR(a, b);
1377  }
1378 }

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

◆ TEST() [154/370]

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

Definition at line 1275 of file geometry_unittests.cc.

1275  {
1276  {
1277  Color a(1.0, 0.5, 0.2, 0.5);
1278  Color premultiplied = a.Premultiply();
1279  Color expected = Color(0.5, 0.25, 0.1, 0.5);
1280  ASSERT_COLOR_NEAR(premultiplied, expected);
1281  }
1282 
1283  {
1284  Color a(0.5, 0.25, 0.1, 0.5);
1285  Color unpremultiplied = a.Unpremultiply();
1286  Color expected = Color(1.0, 0.5, 0.2, 0.5);
1287  ASSERT_COLOR_NEAR(unpremultiplied, expected);
1288  }
1289 
1290  {
1291  Color a(0.5, 0.25, 0.1, 0.0);
1292  Color unpremultiplied = a.Unpremultiply();
1293  Color expected = Color(0.0, 0.0, 0.0, 0.0);
1294  ASSERT_COLOR_NEAR(unpremultiplied, expected);
1295  }
1296 }

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

◆ TEST() [155/370]

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

Definition at line 1695 of file geometry_unittests.cc.

1695  {
1696  {
1697  std::stringstream stream;
1698  Color m;
1699  stream << m;
1700  ASSERT_EQ(stream.str(), "(0, 0, 0, 0)");
1701  }
1702 
1703  {
1704  std::stringstream stream;
1705  Color m(1, 2, 3, 4);
1706  stream << m;
1707  ASSERT_EQ(stream.str(), "(1, 2, 3, 4)");
1708  }
1709 }

◆ TEST() [156/370]

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

Definition at line 1298 of file geometry_unittests.cc.

1298  {
1299  {
1300  Color a(1.0, 0.5, 0.2, 0.5);
1301  std::array<uint8_t, 4> expected = {255, 128, 51, 128};
1302  ASSERT_ARRAY_4_NEAR(a.ToR8G8B8A8(), expected);
1303  }
1304 
1305  {
1306  Color a(0.0, 0.0, 0.0, 0.0);
1307  std::array<uint8_t, 4> expected = {0, 0, 0, 0};
1308  ASSERT_ARRAY_4_NEAR(a.ToR8G8B8A8(), expected);
1309  }
1310 
1311  {
1312  Color a(1.0, 1.0, 1.0, 1.0);
1313  std::array<uint8_t, 4> expected = {255, 255, 255, 255};
1314  ASSERT_ARRAY_4_NEAR(a.ToR8G8B8A8(), expected);
1315  }
1316 }

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

◆ TEST() [157/370]

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

Definition at line 1426 of file geometry_unittests.cc.

1426  {
1427  {
1428  auto result = Color::White().SRGBToLinear();
1429  auto expected = Color(1, 1, 1, 1);
1430  ASSERT_COLOR_NEAR(result, expected);
1431  }
1432 
1433  {
1434  auto result = Color::BlackTransparent().SRGBToLinear();
1435  auto expected = Color(0, 0, 0, 0);
1436  ASSERT_COLOR_NEAR(result, expected);
1437  }
1438 
1439  {
1440  auto result = Color(0.2, 0.4, 0.6, 0.8).SRGBToLinear();
1441  auto expected = Color(0.0331048, 0.132868, 0.318547, 0.8);
1442  ASSERT_COLOR_NEAR(result, expected);
1443  }
1444 }

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

◆ TEST() [158/370]

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

Definition at line 115 of file geometry_unittests.cc.

115  {
116  auto matrix = Matrix{3, 4, 14, 155, 2, 1, 3, 4, 2, 3, 2, 1, 1, 2, 4, 2};
117  ASSERT_EQ(matrix.GetDeterminant(), -1889);
118 }

◆ TEST() [159/370]

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

Definition at line 1717 of file geometry_unittests.cc.

1717  {
1718  {
1719  // Simple 2 color gradient produces color buffer containing exactly those
1720  // values.
1721  std::vector<Color> colors = {Color::Red(), Color::Blue()};
1722  std::vector<Scalar> stops = {0.0, 1.0};
1723 
1724  auto gradient = CreateGradientBuffer(colors, stops);
1725 
1726  ASSERT_COLOR_BUFFER_NEAR(gradient.color_bytes, colors);
1727  ASSERT_EQ(gradient.texture_size, 2u);
1728  }
1729 
1730  {
1731  // Gradient with duplicate stops does not create an empty texture.
1732  std::vector<Color> colors = {Color::Red(), Color::Yellow(), Color::Black(),
1733  Color::Blue()};
1734  std::vector<Scalar> stops = {0.0, 0.25, 0.25, 1.0};
1735 
1736  auto gradient = CreateGradientBuffer(colors, stops);
1737  ASSERT_EQ(gradient.texture_size, 5u);
1738  }
1739 
1740  {
1741  // Simple N color gradient produces color buffer containing exactly those
1742  // values.
1743  std::vector<Color> colors = {Color::Red(), Color::Blue(), Color::Green(),
1744  Color::White()};
1745  std::vector<Scalar> stops = {0.0, 0.33, 0.66, 1.0};
1746 
1747  auto gradient = CreateGradientBuffer(colors, stops);
1748 
1749  ASSERT_COLOR_BUFFER_NEAR(gradient.color_bytes, colors);
1750  ASSERT_EQ(gradient.texture_size, 4u);
1751  }
1752 
1753  {
1754  // Gradient with color stops will lerp and scale buffer.
1755  std::vector<Color> colors = {Color::Red(), Color::Blue(), Color::Green()};
1756  std::vector<Scalar> stops = {0.0, 0.25, 1.0};
1757 
1758  auto gradient = CreateGradientBuffer(colors, stops);
1759 
1760  std::vector<Color> lerped_colors = {
1761  Color::Red(),
1762  Color::Blue(),
1763  Color::Lerp(Color::Blue(), Color::Green(), 0.3333),
1764  Color::Lerp(Color::Blue(), Color::Green(), 0.6666),
1765  Color::Green(),
1766  };
1767  ASSERT_COLOR_BUFFER_NEAR(gradient.color_bytes, lerped_colors);
1768  ASSERT_EQ(gradient.texture_size, 5u);
1769  }
1770 
1771  {
1772  // Gradient size is capped at 1024.
1773  std::vector<Color> colors = {};
1774  std::vector<Scalar> stops = {};
1775  for (auto i = 0u; i < 1025; i++) {
1776  colors.push_back(Color::Blue());
1777  stops.push_back(i / 1025.0);
1778  }
1779 
1780  auto gradient = CreateGradientBuffer(colors, stops);
1781 
1782  ASSERT_EQ(gradient.texture_size, 1024u);
1783  ASSERT_EQ(gradient.color_bytes.size(), 1024u * 4);
1784  }
1785 }

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

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

Definition at line 1787 of file geometry_unittests.cc.

1787  {
1788 #if defined(FML_OS_MACOSX) || defined(FML_OS_IOS) || \
1789  defined(FML_OS_IOS_SIMULATOR)
1790  ASSERT_EQ(ScalarToHalf(0.0), 0.0f16);
1791  ASSERT_EQ(ScalarToHalf(0.05), 0.05f16);
1792  ASSERT_EQ(ScalarToHalf(2.43), 2.43f16);
1793  ASSERT_EQ(ScalarToHalf(-1.45), -1.45f16);
1794 
1795  // 65504 is the largest possible half.
1796  ASSERT_EQ(ScalarToHalf(65504.0f), 65504.0f16);
1797  ASSERT_EQ(ScalarToHalf(65504.0f + 1), 65504.0f16);
1798 
1799  // Colors
1800  ASSERT_EQ(HalfVector4(Color::Red()),
1801  HalfVector4(1.0f16, 0.0f16, 0.0f16, 1.0f16));
1802  ASSERT_EQ(HalfVector4(Color::Green()),
1803  HalfVector4(0.0f16, 1.0f16, 0.0f16, 1.0f16));
1804  ASSERT_EQ(HalfVector4(Color::Blue()),
1805  HalfVector4(0.0f16, 0.0f16, 1.0f16, 1.0f16));
1806  ASSERT_EQ(HalfVector4(Color::Black().WithAlpha(0)),
1807  HalfVector4(0.0f16, 0.0f16, 0.0f16, 0.0f16));
1808 
1809  ASSERT_EQ(HalfVector3(Vector3(4.0, 6.0, -1.0)),
1810  HalfVector3(4.0f16, 6.0f16, -1.0f16));
1811  ASSERT_EQ(HalfVector2(Vector2(4.0, 6.0)), HalfVector2(4.0f16, 6.0f16));
1812 
1813  ASSERT_EQ(Half(0.5f), Half(0.5f16));
1814  ASSERT_EQ(Half(0.5), Half(0.5f16));
1815  ASSERT_EQ(Half(5), Half(5.0f16));
1816 #else
1817  GTEST_SKIP() << "Half-precision floats (IEEE 754) are not portable and "
1818  "only used on Apple platforms.";
1819 #endif // FML_OS_MACOSX || FML_OS_IOS || FML_OS_IOS_SIMULATOR
1820 }

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

◆ TEST() [161/370]

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

Definition at line 120 of file geometry_unittests.cc.

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

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

◆ TEST() [162/370]

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

Definition at line 75 of file geometry_unittests.cc.

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

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

◆ TEST() [163/370]

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

Definition at line 38 of file geometry_unittests.cc.

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

References impeller::Matrix::MakeColumn().

◆ TEST() [164/370]

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

Definition at line 52 of file geometry_unittests.cc.

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

References impeller::Matrix::MakeRow().

◆ TEST() [165/370]

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

Definition at line 96 of file geometry_unittests.cc.

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

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

◆ TEST() [166/370]

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

Definition at line 417 of file geometry_unittests.cc.

417  {
418  {
419  auto m = Matrix();
420  Vector3 x = m.GetBasisX();
421  Vector3 y = m.GetBasisY();
422  Vector3 z = m.GetBasisZ();
423  ASSERT_VECTOR3_NEAR(x, Vector3(1, 0, 0));
424  ASSERT_VECTOR3_NEAR(y, Vector3(0, 1, 0));
425  ASSERT_VECTOR3_NEAR(z, Vector3(0, 0, 1));
426  }
427 
428  {
429  auto m = Matrix::MakeRotationZ(Radians{kPiOver2}) *
430  Matrix::MakeRotationX(Radians{kPiOver2}) *
431  Matrix::MakeScale(Vector3(2, 3, 4));
432  Vector3 x = m.GetBasisX();
433  Vector3 y = m.GetBasisY();
434  Vector3 z = m.GetBasisZ();
435  ASSERT_VECTOR3_NEAR(x, Vector3(0, 2, 0));
436  ASSERT_VECTOR3_NEAR(y, Vector3(0, 0, 3));
437  ASSERT_VECTOR3_NEAR(z, Vector3(4, 0, 0));
438  }
439 }

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

◆ TEST() [167/370]

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

Definition at line 441 of file geometry_unittests.cc.

441  {
442  {
443  auto m = Matrix();
444  Scalar result = m.GetDirectionScale(Vector3{1, 0, 0});
445  ASSERT_FLOAT_EQ(result, 1);
446  }
447 
448  {
449  auto m = Matrix::MakeRotationX(Degrees{10}) *
450  Matrix::MakeRotationY(Degrees{83}) *
451  Matrix::MakeRotationZ(Degrees{172});
452  Scalar result = m.GetDirectionScale(Vector3{0, 1, 0});
453  ASSERT_FLOAT_EQ(result, 1);
454  }
455 
456  {
457  auto m = Matrix::MakeRotationZ(Radians{kPiOver2}) *
458  Matrix::MakeScale(Vector3(3, 4, 5));
459  Scalar result = m.GetDirectionScale(Vector3{2, 0, 0});
460  ASSERT_FLOAT_EQ(result, 8);
461  }
462 }

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

◆ TEST() [168/370]

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

Definition at line 327 of file geometry_unittests.cc.

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

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

◆ TEST() [169/370]

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

Definition at line 342 of file geometry_unittests.cc.

342  {
343  {
344  auto m = Matrix::MakeScale({3, 1, 1});
345  ASSERT_EQ(m.GetMaxBasisLengthXY(), 3);
346 
347  m = m * Matrix::MakeSkew(0, 4);
348  ASSERT_EQ(m.GetMaxBasisLengthXY(), 5);
349  }
350 
351  {
352  auto m = Matrix::MakeScale({-3, 4, 7});
353  ASSERT_EQ(m.GetMaxBasisLengthXY(), 4);
354  }
355 
356  {
357  // clang-format off
358  auto m = Matrix::MakeColumn(
359  1.0f, 0.0f, 0.0f, 0.0f,
360  0.0f, 1.0f, 0.0f, 0.0f,
361  4.0f, 0.0f, 1.0f, 0.0f,
362  0.0f, 0.0f, 0.0f, 1.0f
363  );
364  // clang-format on
365  ASSERT_EQ(m.GetMaxBasisLengthXY(), 1.0f);
366  }
367 }

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

◆ TEST() [170/370]

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

Definition at line 464 of file geometry_unittests.cc.

464  {
465  {
466  auto m = Matrix::MakeTranslation({1, 2, 3});
467  bool result = m.IsAligned();
468  ASSERT_TRUE(result);
469  }
470 
471  {
472  auto m = Matrix::MakeRotationZ(Degrees{123});
473  bool result = m.IsAligned();
474  ASSERT_FALSE(result);
475  }
476 }

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

◆ TEST() [171/370]

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

Definition at line 504 of file geometry_unittests.cc.

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

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

◆ TEST() [172/370]

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

Definition at line 369 of file geometry_unittests.cc.

369  {
370  {
371  auto m = Matrix::MakeOrthographic(Size(100, 200));
372  auto expect = Matrix{
373  0.02, 0, 0, 0, //
374  0, -0.01, 0, 0, //
375  0, 0, 0, 0, //
376  -1, 1, 0.5, 1, //
377  };
378  ASSERT_MATRIX_NEAR(m, expect);
379  }
380 
381  {
382  auto m = Matrix::MakeOrthographic(Size(400, 100));
383  auto expect = Matrix{
384  0.005, 0, 0, 0, //
385  0, -0.02, 0, 0, //
386  0, 0, 0, 0, //
387  -1, 1, 0.5, 1, //
388  };
389  ASSERT_MATRIX_NEAR(m, expect);
390  }
391 }

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

◆ TEST() [173/370]

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

Definition at line 393 of file geometry_unittests.cc.

393  {
394  {
395  auto m = Matrix::MakePerspective(Degrees(60), Size(100, 200), 1, 10);
396  auto expect = Matrix{
397  3.4641, 0, 0, 0, //
398  0, 1.73205, 0, 0, //
399  0, 0, 1.11111, 1, //
400  0, 0, -1.11111, 0, //
401  };
402  ASSERT_MATRIX_NEAR(m, expect);
403  }
404 
405  {
406  auto m = Matrix::MakePerspective(Radians(1), 2, 10, 20);
407  auto expect = Matrix{
408  0.915244, 0, 0, 0, //
409  0, 1.83049, 0, 0, //
410  0, 0, 2, 1, //
411  0, 0, -20, 0, //
412  };
413  ASSERT_MATRIX_NEAR(m, expect);
414  }
415 }

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

◆ TEST() [174/370]

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

Definition at line 272 of file geometry_unittests.cc.

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

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

◆ TEST() [175/370]

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

Definition at line 1620 of file geometry_unittests.cc.

1620  {
1621  {
1622  std::stringstream stream;
1623  Matrix m;
1624  stream << m;
1625  ASSERT_EQ(stream.str(), R"((
1626  1.000000, 0.000000, 0.000000, 0.000000,
1627  0.000000, 1.000000, 0.000000, 0.000000,
1628  0.000000, 0.000000, 1.000000, 0.000000,
1629  0.000000, 0.000000, 0.000000, 1.000000,
1630 ))");
1631  }
1632 
1633  {
1634  std::stringstream stream;
1635  Matrix m = Matrix::MakeTranslation(Vector3(10, 20, 30));
1636  stream << m;
1637 
1638  ASSERT_EQ(stream.str(), R"((
1639  1.000000, 0.000000, 0.000000, 10.000000,
1640  0.000000, 1.000000, 0.000000, 20.000000,
1641  0.000000, 0.000000, 1.000000, 30.000000,
1642  0.000000, 0.000000, 0.000000, 1.000000,
1643 ))");
1644  }
1645 }

References impeller::Matrix::MakeTranslation().

◆ TEST() [176/370]

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

Definition at line 292 of file geometry_unittests.cc.

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

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

◆ TEST() [177/370]

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

Definition at line 478 of file geometry_unittests.cc.

478  {
479  {
480  auto m = Matrix();
481  bool result = m.IsTranslationScaleOnly();
482  ASSERT_TRUE(result);
483  }
484 
485  {
486  auto m = Matrix::MakeScale(Vector3(2, 3, 4));
487  bool result = m.IsTranslationScaleOnly();
488  ASSERT_TRUE(result);
489  }
490 
491  {
492  auto m = Matrix::MakeTranslation(Vector3(2, 3, 4));
493  bool result = m.IsTranslationScaleOnly();
494  ASSERT_TRUE(result);
495  }
496 
497  {
498  auto m = Matrix::MakeRotationZ(Degrees(10));
499  bool result = m.IsTranslationScaleOnly();
500  ASSERT_FALSE(result);
501  }
502 }

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

◆ TEST() [178/370]

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

Definition at line 207 of file geometry_unittests.cc.

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

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

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

Definition at line 109 of file geometry_unittests.cc.

109  {
110  auto rotation = Matrix::MakeRotationZ(Radians{kPiOver4});
111  auto invert = rotation.Invert();
112  ASSERT_MATRIX_NEAR(rotation * invert, Matrix{});
113 }

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

◆ TEST() [180/370]

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

Definition at line 961 of file geometry_unittests.cc.

961  {
962  Point a(-1, -2);
963  auto a_abs = a.Abs();
964  auto expected = Point(1, 2);
965  ASSERT_POINT_NEAR(a_abs, expected);
966 }

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

◆ TEST() [181/370]

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

Definition at line 968 of file geometry_unittests.cc.

968  {
969  // Negative result in the CCW (with up = -Y) direction.
970  {
971  Point a(1, 1);
972  Point b(1, -1);
973  Radians actual = a.AngleTo(b);
974  Radians expected = Radians{-kPi / 2};
975  ASSERT_FLOAT_EQ(actual.radians, expected.radians);
976  }
977 
978  // Check the other direction to ensure the result is signed correctly.
979  {
980  Point a(1, -1);
981  Point b(1, 1);
982  Radians actual = a.AngleTo(b);
983  Radians expected = Radians{kPi / 2};
984  ASSERT_FLOAT_EQ(actual.radians, expected.radians);
985  }
986 
987  // Differences in magnitude should have no impact on the result.
988  {
989  Point a(100, -100);
990  Point b(0.01, 0.01);
991  Radians actual = a.AngleTo(b);
992  Radians expected = Radians{kPi / 2};
993  ASSERT_FLOAT_EQ(actual.radians, expected.radians);
994  }
995 }

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

◆ TEST() [182/370]

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

Definition at line 1060 of file geometry_unittests.cc.

1060  {
1061  Point p(1.5, 2.3);
1062  Point result = p.Ceil();
1063  Point expected(2, 3);
1064  ASSERT_POINT_NEAR(result, expected);
1065 }

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

◆ TEST() [183/370]

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

Definition at line 916 of file geometry_unittests.cc.

916  {
917  {
918  Point p(1, 0);
919  Scalar s = p.Cross(Point(-1, 0));
920  ASSERT_FLOAT_EQ(s, 0);
921  }
922 
923  {
924  Point p(0, -1);
925  Scalar s = p.Cross(Point(-1, 0));
926  ASSERT_FLOAT_EQ(s, -1);
927  }
928 
929  {
930  Point p(1, 2);
931  Scalar s = p.Cross(Point(3, -4));
932  ASSERT_FLOAT_EQ(s, -10);
933  }
934 }

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

◆ TEST() [184/370]

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

Definition at line 896 of file geometry_unittests.cc.

896  {
897  {
898  Point p(1, 0);
899  Scalar s = p.Dot(Point(-1, 0));
900  ASSERT_FLOAT_EQ(s, -1);
901  }
902 
903  {
904  Point p(0, -1);
905  Scalar s = p.Dot(Point(-1, 0));
906  ASSERT_FLOAT_EQ(s, 0);
907  }
908 
909  {
910  Point p(1, 2);
911  Scalar s = p.Dot(Point(3, -4));
912  ASSERT_FLOAT_EQ(s, -5);
913  }
914 }

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

◆ TEST() [185/370]

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

Definition at line 1039 of file geometry_unittests.cc.

1039  {
1040  Point p(1.5, 2.3);
1041  Point result = p.Floor();
1042  Point expected(1, 2);
1043  ASSERT_POINT_NEAR(result, expected);
1044 }

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

◆ TEST() [186/370]

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

Definition at line 701 of file geometry_unittests.cc.

701  {
702  // Integer on LHS, float on RHS
703  {
704  IPoint p1(1, 2);
705  Point p2 = p1 + Point(1, 2);
706  ASSERT_FLOAT_EQ(p2.x, 2u);
707  ASSERT_FLOAT_EQ(p2.y, 4u);
708  }
709 
710  {
711  IPoint p1(3, 6);
712  Point p2 = p1 - Point(1, 2);
713  ASSERT_FLOAT_EQ(p2.x, 2u);
714  ASSERT_FLOAT_EQ(p2.y, 4u);
715  }
716 
717  {
718  IPoint p1(1, 2);
719  Point p2 = p1 * Point(2, 3);
720  ASSERT_FLOAT_EQ(p2.x, 2u);
721  ASSERT_FLOAT_EQ(p2.y, 6u);
722  }
723 
724  {
725  IPoint p1(2, 6);
726  Point p2 = p1 / Point(2, 3);
727  ASSERT_FLOAT_EQ(p2.x, 1u);
728  ASSERT_FLOAT_EQ(p2.y, 2u);
729  }
730 
731  // Float on LHS, integer on RHS
732  {
733  Point p1(1, 2);
734  Point p2 = p1 + IPoint(1, 2);
735  ASSERT_FLOAT_EQ(p2.x, 2u);
736  ASSERT_FLOAT_EQ(p2.y, 4u);
737  }
738 
739  {
740  Point p1(3, 6);
741  Point p2 = p1 - IPoint(1, 2);
742  ASSERT_FLOAT_EQ(p2.x, 2u);
743  ASSERT_FLOAT_EQ(p2.y, 4u);
744  }
745 
746  {
747  Point p1(1, 2);
748  Point p2 = p1 * IPoint(2, 3);
749  ASSERT_FLOAT_EQ(p2.x, 2u);
750  ASSERT_FLOAT_EQ(p2.y, 6u);
751  }
752 
753  {
754  Point p1(2, 6);
755  Point p2 = p1 / IPoint(2, 3);
756  ASSERT_FLOAT_EQ(p2.x, 1u);
757  ASSERT_FLOAT_EQ(p2.y, 2u);
758  }
759 }

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

◆ TEST() [187/370]

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

Definition at line 1102 of file geometry_unittests.cc.

1102  {
1103  Point p(1, 2);
1104  Point result = p.Lerp({5, 10}, 0.75);
1105  Point expected(4, 8);
1106  ASSERT_POINT_NEAR(result, expected);
1107 }

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

◆ TEST() [188/370]

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

Definition at line 1018 of file geometry_unittests.cc.

1018  {
1019  Point p(1, 2);
1020  Point result = p.Max({0, 10});
1021  Point expected(1, 10);
1022  ASSERT_POINT_NEAR(result, expected);
1023 }

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

◆ TEST() [189/370]

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

Definition at line 997 of file geometry_unittests.cc.

997  {
998  Point p(1, 2);
999  Point result = p.Min({0, 10});
1000  Point expected(0, 2);
1001  ASSERT_POINT_NEAR(result, expected);
1002 }

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

◆ TEST() [190/370]

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

Definition at line 1647 of file geometry_unittests.cc.

1647  {
1648  {
1649  std::stringstream stream;
1650  Point m;
1651  stream << m;
1652  ASSERT_EQ(stream.str(), "(0, 0)");
1653  }
1654 
1655  {
1656  std::stringstream stream;
1657  Point m(13, 37);
1658  stream << m;
1659  ASSERT_EQ(stream.str(), "(13, 37)");
1660  }
1661 }

◆ TEST() [191/370]

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

Definition at line 936 of file geometry_unittests.cc.

936  {
937  {
938  Point axis = Point(0, 1);
939  Point a(2, 3);
940  auto reflected = a.Reflect(axis);
941  auto expected = Point(2, -3);
942  ASSERT_POINT_NEAR(reflected, expected);
943  }
944 
945  {
946  Point axis = Point(1, 1).Normalize();
947  Point a(1, 0);
948  auto reflected = a.Reflect(axis);
949  auto expected = Point(0, -1);
950  ASSERT_POINT_NEAR(reflected, expected);
951  }
952 
953  {
954  Point axis = Point(1, 1).Normalize();
955  Point a(-1, -1);
956  auto reflected = a.Reflect(axis);
957  ASSERT_POINT_NEAR(reflected, -a);
958  }
959 }

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

◆ TEST() [192/370]

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

Definition at line 1081 of file geometry_unittests.cc.

1081  {
1082  Point p(1.5, 2.3);
1083  Point result = p.Round();
1084  Point expected(2, 2);
1085  ASSERT_POINT_NEAR(result, expected);
1086 }

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

◆ TEST() [193/370]

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

Definition at line 550 of file geometry_unittests.cc.

550  {
551  auto q1 = Quaternion{{0.0, 0.0, 1.0}, 0.0};
552  auto q2 = Quaternion{{0.0, 0.0, 1.0}, kPiOver4};
553 
554  auto q3 = q1.Slerp(q2, 0.5);
555 
556  auto expected = Quaternion{{0.0, 0.0, 1.0}, kPiOver4 / 2.0};
557 
558  ASSERT_QUATERNION_NEAR(q3, expected);
559 }

References ASSERT_QUATERNION_NEAR, and impeller::kPiOver4.

◆ TEST() [194/370]

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

Definition at line 561 of file geometry_unittests.cc.

561  {
562  {
563  Quaternion q({0, 0, 1}, 0);
564  Vector3 v(0, 1, 0);
565 
566  Vector3 result = q * v;
567  Vector3 expected(0, 1, 0);
568 
569  ASSERT_VECTOR3_NEAR(result, expected);
570  }
571 
572  {
573  Quaternion q({0, 0, 1}, k2Pi);
574  Vector3 v(1, 0, 0);
575 
576  Vector3 result = q * v;
577  Vector3 expected(1, 0, 0);
578 
579  ASSERT_VECTOR3_NEAR(result, expected);
580  }
581 
582  {
583  Quaternion q({0, 0, 1}, kPiOver4);
584  Vector3 v(0, 1, 0);
585 
586  Vector3 result = q * v;
587  Vector3 expected(-k1OverSqrt2, k1OverSqrt2, 0);
588 
589  ASSERT_VECTOR3_NEAR(result, expected);
590  }
591 
592  {
593  Quaternion q(Vector3(1, 0, 1).Normalize(), kPi);
594  Vector3 v(0, 0, -1);
595 
596  Vector3 result = q * v;
597  Vector3 expected(-1, 0, 0);
598 
599  ASSERT_VECTOR3_NEAR(result, expected);
600  }
601 }

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

◆ TEST() [195/370]

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

Definition at line 66 of file geometry_unittests.cc.

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

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

◆ TEST() [196/370]

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

Definition at line 29 of file geometry_unittests.cc.

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

References impeller::ScalarNearlyEqual().

◆ TEST() [197/370]

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

Definition at line 761 of file geometry_unittests.cc.

761  {
762  // Point on LHS, Size on RHS
763  {
764  IPoint p1(1, 2);
765  IPoint p2 = p1 + ISize(1, 2);
766  ASSERT_EQ(p2.x, 2u);
767  ASSERT_EQ(p2.y, 4u);
768  }
769 
770  {
771  IPoint p1(3, 6);
772  IPoint p2 = p1 - ISize(1, 2);
773  ASSERT_EQ(p2.x, 2u);
774  ASSERT_EQ(p2.y, 4u);
775  }
776 
777  {
778  IPoint p1(1, 2);
779  IPoint p2 = p1 * ISize(2, 3);
780  ASSERT_EQ(p2.x, 2u);
781  ASSERT_EQ(p2.y, 6u);
782  }
783 
784  {
785  IPoint p1(2, 6);
786  IPoint p2 = p1 / ISize(2, 3);
787  ASSERT_EQ(p2.x, 1u);
788  ASSERT_EQ(p2.y, 2u);
789  }
790 
791  // Size on LHS, Point on RHS
792  {
793  ISize p1(1, 2);
794  IPoint p2 = p1 + IPoint(1, 2);
795  ASSERT_EQ(p2.x, 2u);
796  ASSERT_EQ(p2.y, 4u);
797  }
798 
799  {
800  ISize p1(3, 6);
801  IPoint p2 = p1 - IPoint(1, 2);
802  ASSERT_EQ(p2.x, 2u);
803  ASSERT_EQ(p2.y, 4u);
804  }
805 
806  {
807  ISize p1(1, 2);
808  IPoint p2 = p1 * IPoint(2, 3);
809  ASSERT_EQ(p2.x, 2u);
810  ASSERT_EQ(p2.y, 6u);
811  }
812 
813  {
814  ISize p1(2, 6);
815  IPoint p2 = p1 / IPoint(2, 3);
816  ASSERT_EQ(p2.x, 1u);
817  ASSERT_EQ(p2.y, 2u);
818  }
819 }

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

◆ TEST() [198/370]

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

Definition at line 136 of file geometry_unittests.cc.

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

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

◆ TEST() [199/370]

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

Definition at line 149 of file geometry_unittests.cc.

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

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

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

Definition at line 173 of file geometry_unittests.cc.

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

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

◆ TEST() [201/370]

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

Definition at line 195 of file geometry_unittests.cc.

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

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

◆ TEST() [202/370]

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

Definition at line 1711 of file geometry_unittests.cc.

1711  {
1712  ASSERT_EQ(Color::ToIColor(Color(0, 0, 0, 0)), 0u);
1713  ASSERT_EQ(Color::ToIColor(Color(1.0, 1.0, 1.0, 1.0)), 0xFFFFFFFF);
1714  ASSERT_EQ(Color::ToIColor(Color(0.5, 0.5, 1.0, 1.0)), 0xFF8080FF);
1715 }

References impeller::Color::ToIColor().

◆ TEST() [203/370]

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

Definition at line 1067 of file geometry_unittests.cc.

1067  {
1068  Vector3 p(1.5, 2.3, 3.9);
1069  Vector3 result = p.Ceil();
1070  Vector3 expected(2, 3, 4);
1071  ASSERT_VECTOR3_NEAR(result, expected);
1072 }

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

◆ TEST() [204/370]

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

Definition at line 1046 of file geometry_unittests.cc.

1046  {
1047  Vector3 p(1.5, 2.3, 3.9);
1048  Vector3 result = p.Floor();
1049  Vector3 expected(1, 2, 3);
1050  ASSERT_VECTOR3_NEAR(result, expected);
1051 }

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

◆ TEST() [205/370]

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

Definition at line 1109 of file geometry_unittests.cc.

1109  {
1110  Vector3 p(1, 2, 3);
1111  Vector3 result = p.Lerp({5, 10, 15}, 0.75);
1112  Vector3 expected(4, 8, 12);
1113  ASSERT_VECTOR3_NEAR(result, expected);
1114 }

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

◆ TEST() [206/370]

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

Definition at line 1025 of file geometry_unittests.cc.

1025  {
1026  Vector3 p(1, 2, 3);
1027  Vector3 result = p.Max({0, 10, 2});
1028  Vector3 expected(1, 10, 3);
1029  ASSERT_VECTOR3_NEAR(result, expected);
1030 }

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

◆ TEST() [207/370]

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

Definition at line 1004 of file geometry_unittests.cc.

1004  {
1005  Vector3 p(1, 2, 3);
1006  Vector3 result = p.Min({0, 10, 2});
1007  Vector3 expected(0, 2, 2);
1008  ASSERT_VECTOR3_NEAR(result, expected);
1009 }

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

◆ TEST() [208/370]

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

Definition at line 1663 of file geometry_unittests.cc.

1663  {
1664  {
1665  std::stringstream stream;
1666  Vector3 m;
1667  stream << m;
1668  ASSERT_EQ(stream.str(), "(0, 0, 0)");
1669  }
1670 
1671  {
1672  std::stringstream stream;
1673  Vector3 m(1, 2, 3);
1674  stream << m;
1675  ASSERT_EQ(stream.str(), "(1, 2, 3)");
1676  }
1677 }

◆ TEST() [209/370]

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

Definition at line 1088 of file geometry_unittests.cc.

1088  {
1089  Vector3 p(1.5, 2.3, 3.9);
1090  Vector3 result = p.Round();
1091  Vector3 expected(2, 2, 4);
1092  ASSERT_VECTOR3_NEAR(result, expected);
1093 }

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

◆ TEST() [210/370]

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

Definition at line 1074 of file geometry_unittests.cc.

1074  {
1075  Vector4 p(1.5, 2.3, 3.9, 4.0);
1076  Vector4 result = p.Ceil();
1077  Vector4 expected(2, 3, 4, 4);
1078  ASSERT_VECTOR4_NEAR(result, expected);
1079 }

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

◆ TEST() [211/370]

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

Definition at line 1053 of file geometry_unittests.cc.

1053  {
1054  Vector4 p(1.5, 2.3, 3.9, 4.0);
1055  Vector4 result = p.Floor();
1056  Vector4 expected(1, 2, 3, 4);
1057  ASSERT_VECTOR4_NEAR(result, expected);
1058 }

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

◆ TEST() [212/370]

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

Definition at line 1116 of file geometry_unittests.cc.

1116  {
1117  Vector4 p(1, 2, 3, 4);
1118  Vector4 result = p.Lerp({5, 10, 15, 20}, 0.75);
1119  Vector4 expected(4, 8, 12, 16);
1120  ASSERT_VECTOR4_NEAR(result, expected);
1121 }

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

◆ TEST() [213/370]

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

Definition at line 1032 of file geometry_unittests.cc.

1032  {
1033  Vector4 p(1, 2, 3, 4);
1034  Vector4 result = p.Max({0, 10, 2, 1});
1035  Vector4 expected(1, 10, 3, 4);
1036  ASSERT_VECTOR4_NEAR(result, expected);
1037 }

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

◆ TEST() [214/370]

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

Definition at line 1011 of file geometry_unittests.cc.

1011  {
1012  Vector4 p(1, 2, 3, 4);
1013  Vector4 result = p.Min({0, 10, 2, 1});
1014  Vector4 expected(0, 2, 2, 1);
1015  ASSERT_VECTOR4_NEAR(result, expected);
1016 }

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

◆ TEST() [215/370]

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

Definition at line 1679 of file geometry_unittests.cc.

1679  {
1680  {
1681  std::stringstream stream;
1682  Vector4 m;
1683  stream << m;
1684  ASSERT_EQ(stream.str(), "(0, 0, 0, 1)");
1685  }
1686 
1687  {
1688  std::stringstream stream;
1689  Vector4 m(1, 2, 3, 4);
1690  stream << m;
1691  ASSERT_EQ(stream.str(), "(1, 2, 3, 4)");
1692  }
1693 }

◆ TEST() [216/370]

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

Definition at line 1095 of file geometry_unittests.cc.

1095  {
1096  Vector4 p(1.5, 2.3, 3.9, 4.0);
1097  Vector4 result = p.Round();
1098  Vector4 expected(2, 2, 4, 4);
1099  ASSERT_VECTOR4_NEAR(result, expected);
1100 }

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

◆ TEST() [217/370]

impeller::testing::TEST ( MatrixTest  ,
Multiply   
)

Definition at line 14 of file matrix_unittests.cc.

14  {
15  Matrix x(0.0, 0.0, 0.0, 1.0, //
16  1.0, 0.0, 0.0, 1.0, //
17  0.0, 1.0, 0.0, 1.0, //
18  1.0, 1.0, 0.0, 1.0);
19  Matrix translate = Matrix::MakeTranslation({10, 20, 0});
20  Matrix result = translate * x;
21  EXPECT_TRUE(MatrixNear(result, Matrix(10.0, 20.0, 0.0, 1.0, //
22  11.0, 20.0, 0.0, 1.0, //
23  10.0, 21.0, 0.0, 1.0, //
24  11.0, 21.0, 0.0, 1.0)));
25 }

References impeller::Matrix::MakeTranslation(), and MatrixNear().

◆ TEST() [218/370]

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

Definition at line 339 of file path_unittests.cc.

339  {
340  PathBuilder builder;
341  auto path =
342  builder.AddCubicCurve({120, 160}, {25, 200}, {220, 260}, {220, 40})
343  .TakePath();
344  auto box = path.GetBoundingBox();
345  Rect expected = Rect::MakeXYWH(93.9101, 40, 126.09, 158.862);
346  ASSERT_TRUE(box.has_value());
347  ASSERT_RECT_NEAR(box.value_or(Rect::MakeMaximum()), expected);
348 }

References impeller::PathBuilder::AddCubicCurve(), ASSERT_RECT_NEAR, impeller::TRect< Scalar >::MakeMaximum(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [219/370]

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

Definition at line 350 of file path_unittests.cc.

350  {
351  PathBuilder builder;
352  builder.AddRoundedRect(Rect::MakeXYWH(10, 10, 300, 300), {50, 50, 50, 50});
353  auto path = builder.TakePath();
354  auto actual = path.GetBoundingBox();
355  Rect expected = Rect::MakeXYWH(10, 10, 300, 300);
356 
357  ASSERT_TRUE(actual.has_value());
358  ASSERT_RECT_NEAR(actual.value_or(Rect::MakeMaximum()), expected);
359 }

References impeller::PathBuilder::AddRoundedRect(), ASSERT_RECT_NEAR, impeller::Path::GetBoundingBox(), impeller::TRect< Scalar >::MakeMaximum(), impeller::TRect< Scalar >::MakeXYWH(), and impeller::PathBuilder::TakePath().

◆ TEST() [220/370]

impeller::testing::TEST ( PathTest  ,
CanBeCloned   
)

Definition at line 457 of file path_unittests.cc.

457  {
458  PathBuilder builder;
459  builder.MoveTo({10, 10});
460  builder.LineTo({20, 20});
461  builder.SetBounds(Rect::MakeLTRB(0, 0, 100, 100));
462  builder.SetConvexity(Convexity::kConvex);
463 
464  auto path_a = builder.TakePath(FillType::kOdd);
465  // NOLINTNEXTLINE(performance-unnecessary-copy-initialization)
466  auto path_b = path_a;
467 
468  EXPECT_EQ(path_a.GetBoundingBox(), path_b.GetBoundingBox());
469  EXPECT_EQ(path_a.GetFillType(), path_b.GetFillType());
470  EXPECT_EQ(path_a.IsConvex(), path_b.IsConvex());
471 
472  auto poly_a = path_a.CreatePolyline(1.0);
473  auto poly_b = path_b.CreatePolyline(1.0);
474 
475  ASSERT_EQ(poly_a.points->size(), poly_b.points->size());
476  ASSERT_EQ(poly_a.contours.size(), poly_b.contours.size());
477 
478  for (auto i = 0u; i < poly_a.points->size(); i++) {
479  EXPECT_EQ((*poly_a.points)[i], (*poly_b.points)[i]);
480  }
481 
482  for (auto i = 0u; i < poly_a.contours.size(); i++) {
483  EXPECT_EQ(poly_a.contours[i].start_index, poly_b.contours[i].start_index);
484  EXPECT_EQ(poly_a.contours[i].start_direction,
485  poly_b.contours[i].start_direction);
486  }
487 }

References impeller::kConvex, impeller::kOdd, impeller::PathBuilder::LineTo(), impeller::TRect< Scalar >::MakeLTRB(), impeller::PathBuilder::MoveTo(), impeller::PathBuilder::SetBounds(), impeller::PathBuilder::SetConvexity(), and impeller::PathBuilder::TakePath().

◆ TEST() [221/370]

impeller::testing::TEST ( PathTest  ,
CubicPath   
)

Definition at line 324 of file path_unittests.cc.

324  {
325  PathBuilder builder;
326  auto path =
327  builder.CubicCurveTo(Point(10, 10), Point(-10, -10), Point(20, 20))
328  .TakePath();
329 
330  CubicPathComponent cubic;
331  path.GetCubicComponentAtIndex(1, cubic);
332 
333  EXPECT_EQ(cubic.p1, Point(0, 0));
334  EXPECT_EQ(cubic.cp1, Point(10, 10));
335  EXPECT_EQ(cubic.cp2, Point(-10, -10));
336  EXPECT_EQ(cubic.p2, Point(20, 20));
337 }

References impeller::CubicPathComponent::cp1, impeller::CubicPathComponent::cp2, impeller::PathBuilder::CubicCurveTo(), impeller::CubicPathComponent::p1, impeller::CubicPathComponent::p2, and impeller::PathBuilder::TakePath().

◆ TEST() [222/370]

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

Definition at line 15 of file path_unittests.cc.

15  {
16  CubicPathComponent component({10, 10}, {20, 35}, {35, 20}, {40, 40});
17  std::vector<Point> polyline;
18  component.AppendPolylinePoints(1.0f, polyline);
19  ASSERT_NE(polyline.front().x, 10);
20  ASSERT_NE(polyline.front().y, 10);
21  ASSERT_EQ(polyline.back().x, 40);
22  ASSERT_EQ(polyline.back().y, 40);
23 }

References polyline.

◆ TEST() [223/370]

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

Definition at line 384 of file path_unittests.cc.

384  {
385  auto path = PathBuilder{}.TakePath();
386  ASSERT_EQ(path.GetComponentCount(), 1u);
387 
388  ContourComponent c;
389  path.GetContourComponentAtIndex(0, c);
390  ASSERT_POINT_NEAR(c.destination, Point());
391 
392  Path::Polyline polyline = path.CreatePolyline(1.0f);
393  ASSERT_TRUE(polyline.points->empty());
394  ASSERT_TRUE(polyline.contours.empty());
395 }

References ASSERT_POINT_NEAR, impeller::ContourComponent::destination, polyline, and impeller::PathBuilder::TakePath().

◆ TEST() [224/370]

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

Definition at line 361 of file path_unittests.cc.

361  {
362  CubicPathComponent cubic{{11.769268, 252.883148},
363  {-6.2857933, 204.356461},
364  {-4.53997231, 156.552902},
365  {17.0067291, 109.472488}};
366  auto points = cubic.Extrema();
367 
368  ASSERT_EQ(points.size(), static_cast<size_t>(3));
369  ASSERT_POINT_NEAR(points[2], cubic.Solve(0.455916));
370 }

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

◆ TEST() [225/370]

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

Definition at line 160 of file path_unittests.cc.

160  {
161  Path::Polyline polyline = PathBuilder{}
162  .AddRect(Rect::MakeLTRB(50, 60, 70, 80))
163  .TakePath()
164  .CreatePolyline(1.0f);
165  ASSERT_EQ(polyline.contours.size(), 1u);
166  ASSERT_TRUE(polyline.contours[0].is_closed);
167  ASSERT_EQ(polyline.contours[0].start_index, 0u);
168  ASSERT_EQ(polyline.points->size(), 5u);
169  ASSERT_EQ(polyline.GetPoint(0), Point(50, 60));
170  ASSERT_EQ(polyline.GetPoint(1), Point(70, 60));
171  ASSERT_EQ(polyline.GetPoint(2), Point(70, 80));
172  ASSERT_EQ(polyline.GetPoint(3), Point(50, 80));
173  ASSERT_EQ(polyline.GetPoint(4), Point(50, 60));
174 }

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

◆ TEST() [226/370]

impeller::testing::TEST ( PathTest  ,
PathBuilderDoesNotMutateCopiedPaths   
)

Definition at line 489 of file path_unittests.cc.

489  {
490  auto test_isolation =
491  [](const std::function<void(PathBuilder & builder)>& mutator,
492  bool will_close, Point mutation_offset, const std::string& label) {
493  PathBuilder builder;
494  builder.MoveTo({10, 10});
495  builder.LineTo({20, 20});
496  builder.LineTo({20, 10});
497 
498  auto verify_path = [](const Path& path, bool is_mutated, bool is_closed,
499  Point offset, const std::string& label) {
500  if (is_mutated) {
501  // We can only test the initial state before the mutator did
502  // its work. We have >= 3 components and the first 3 components
503  // will match what we saw before the mutation.
504  EXPECT_GE(path.GetComponentCount(), 3u) << label;
505  } else {
506  EXPECT_EQ(path.GetComponentCount(), 3u) << label;
507  }
508  {
509  ContourComponent contour;
510  EXPECT_TRUE(path.GetContourComponentAtIndex(0, contour)) << label;
511  EXPECT_EQ(contour.destination, offset + Point(10, 10)) << label;
512  EXPECT_EQ(contour.is_closed, is_closed) << label;
513  }
514  {
515  LinearPathComponent line;
516  EXPECT_TRUE(path.GetLinearComponentAtIndex(1, line)) << label;
517  EXPECT_EQ(line.p1, offset + Point(10, 10)) << label;
518  EXPECT_EQ(line.p2, offset + Point(20, 20)) << label;
519  }
520  {
521  LinearPathComponent line;
522  EXPECT_TRUE(path.GetLinearComponentAtIndex(2, line)) << label;
523  EXPECT_EQ(line.p1, offset + Point(20, 20)) << label;
524  EXPECT_EQ(line.p2, offset + Point(20, 10)) << label;
525  }
526  };
527 
528  auto path1 = builder.CopyPath();
529  verify_path(path1, false, false, {},
530  "Initial Path1 state before " + label);
531 
532  for (int i = 0; i < 10; i++) {
533  auto path = builder.CopyPath();
534  verify_path(
535  path, false, false, {},
536  "Extra CopyPath #" + std::to_string(i + 1) + " for " + label);
537  }
538  mutator(builder);
539  verify_path(path1, false, false, {},
540  "Path1 state after subsequent " + label);
541 
542  auto path2 = builder.CopyPath();
543  verify_path(path1, false, false, {},
544  "Path1 state after subsequent " + label + " and CopyPath");
545  verify_path(path2, true, will_close, mutation_offset,
546  "Initial Path2 state with subsequent " + label);
547  };
548 
549  test_isolation(
550  [](PathBuilder& builder) { //
551  builder.SetConvexity(Convexity::kConvex);
552  },
553  false, {}, "SetConvex");
554 
555  test_isolation(
556  [](PathBuilder& builder) { //
557  builder.SetConvexity(Convexity::kUnknown);
558  },
559  false, {}, "SetUnknownConvex");
560 
561  test_isolation(
562  [](PathBuilder& builder) { //
563  builder.Close();
564  },
565  true, {}, "Close");
566 
567  test_isolation(
568  [](PathBuilder& builder) {
569  builder.MoveTo({20, 30}, false);
570  },
571  false, {}, "Absolute MoveTo");
572 
573  test_isolation(
574  [](PathBuilder& builder) {
575  builder.MoveTo({20, 30}, true);
576  },
577  false, {}, "Relative MoveTo");
578 
579  test_isolation(
580  [](PathBuilder& builder) {
581  builder.LineTo({20, 30}, false);
582  },
583  false, {}, "Absolute LineTo");
584 
585  test_isolation(
586  [](PathBuilder& builder) {
587  builder.LineTo({20, 30}, true);
588  },
589  false, {}, "Relative LineTo");
590 
591  test_isolation(
592  [](PathBuilder& builder) { //
593  builder.HorizontalLineTo(100, false);
594  },
595  false, {}, "Absolute HorizontalLineTo");
596 
597  test_isolation(
598  [](PathBuilder& builder) { //
599  builder.HorizontalLineTo(100, true);
600  },
601  false, {}, "Relative HorizontalLineTo");
602 
603  test_isolation(
604  [](PathBuilder& builder) { //
605  builder.VerticalLineTo(100, false);
606  },
607  false, {}, "Absolute VerticalLineTo");
608 
609  test_isolation(
610  [](PathBuilder& builder) { //
611  builder.VerticalLineTo(100, true);
612  },
613  false, {}, "Relative VerticalLineTo");
614 
615  test_isolation(
616  [](PathBuilder& builder) {
617  builder.QuadraticCurveTo({20, 30}, {30, 20}, false);
618  },
619  false, {}, "Absolute QuadraticCurveTo");
620 
621  test_isolation(
622  [](PathBuilder& builder) {
623  builder.QuadraticCurveTo({20, 30}, {30, 20}, true);
624  },
625  false, {}, "Relative QuadraticCurveTo");
626 
627  test_isolation(
628  [](PathBuilder& builder) {
629  builder.CubicCurveTo({20, 30}, {30, 20}, {30, 30}, false);
630  },
631  false, {}, "Absolute CubicCurveTo");
632 
633  test_isolation(
634  [](PathBuilder& builder) {
635  builder.CubicCurveTo({20, 30}, {30, 20}, {30, 30}, true);
636  },
637  false, {}, "Relative CubicCurveTo");
638 
639  test_isolation(
640  [](PathBuilder& builder) {
641  builder.AddLine({100, 100}, {150, 100});
642  },
643  false, {}, "AddLine");
644 
645  test_isolation(
646  [](PathBuilder& builder) {
647  builder.AddRect(Rect::MakeLTRB(100, 100, 120, 120));
648  },
649  false, {}, "AddRect");
650 
651  test_isolation(
652  [](PathBuilder& builder) {
653  builder.AddOval(Rect::MakeLTRB(100, 100, 120, 120));
654  },
655  false, {}, "AddOval");
656 
657  test_isolation(
658  [](PathBuilder& builder) {
659  builder.AddCircle({100, 100}, 20);
660  },
661  false, {}, "AddCircle");
662 
663  test_isolation(
664  [](PathBuilder& builder) {
665  builder.AddArc(Rect::MakeLTRB(100, 100, 120, 120), Degrees(10),
666  Degrees(170));
667  },
668  false, {}, "AddArc");
669 
670  test_isolation(
671  [](PathBuilder& builder) {
672  builder.AddQuadraticCurve({100, 100}, {150, 100}, {150, 150});
673  },
674  false, {}, "AddQuadraticCurve");
675 
676  test_isolation(
677  [](PathBuilder& builder) {
678  builder.AddCubicCurve({100, 100}, {150, 100}, {100, 150}, {150, 150});
679  },
680  false, {}, "AddCubicCurve");
681 
682  test_isolation(
683  [](PathBuilder& builder) {
684  builder.Shift({23, 42});
685  },
686  false, {23, 42}, "Shift");
687 }

References impeller::PathBuilder::AddArc(), impeller::PathBuilder::AddCircle(), impeller::PathBuilder::AddCubicCurve(), impeller::PathBuilder::AddLine(), impeller::PathBuilder::AddOval(), impeller::PathBuilder::AddQuadraticCurve(), impeller::PathBuilder::AddRect(), impeller::PathBuilder::Close(), impeller::PathBuilder::CopyPath(), impeller::PathBuilder::CubicCurveTo(), impeller::ContourComponent::destination, impeller::Path::GetComponentCount(), impeller::Path::GetContourComponentAtIndex(), impeller::Path::GetLinearComponentAtIndex(), impeller::PathBuilder::HorizontalLineTo(), impeller::ContourComponent::is_closed, impeller::kConvex, impeller::kUnknown, impeller::PathBuilder::LineTo(), impeller::TRect< Scalar >::MakeLTRB(), impeller::PathBuilder::MoveTo(), offset, impeller::LinearPathComponent::p1, impeller::LinearPathComponent::p2, impeller::PathBuilder::QuadraticCurveTo(), impeller::PathBuilder::SetConvexity(), impeller::PathBuilder::Shift(), and impeller::PathBuilder::VerticalLineTo().

◆ TEST() [227/370]

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

Definition at line 44 of file path_unittests.cc.

44  {
45  // Closed shapes.
46  {
47  Path path = PathBuilder{}.AddCircle({100, 100}, 50).TakePath();
48  ContourComponent contour;
49  path.GetContourComponentAtIndex(0, contour);
50  ASSERT_POINT_NEAR(contour.destination, Point(100, 50));
51  ASSERT_TRUE(contour.is_closed);
52  }
53 
54  {
55  Path path =
56  PathBuilder{}.AddOval(Rect::MakeXYWH(100, 100, 100, 100)).TakePath();
57  ContourComponent contour;
58  path.GetContourComponentAtIndex(0, contour);
59  ASSERT_POINT_NEAR(contour.destination, Point(150, 100));
60  ASSERT_TRUE(contour.is_closed);
61  }
62 
63  {
64  Path path =
65  PathBuilder{}.AddRect(Rect::MakeXYWH(100, 100, 100, 100)).TakePath();
66  ContourComponent contour;
67  path.GetContourComponentAtIndex(0, contour);
68  ASSERT_POINT_NEAR(contour.destination, Point(100, 100));
69  ASSERT_TRUE(contour.is_closed);
70  }
71 
72  {
73  Path path = PathBuilder{}
74  .AddRoundedRect(Rect::MakeXYWH(100, 100, 100, 100), 10)
75  .TakePath();
76  ContourComponent contour;
77  path.GetContourComponentAtIndex(0, contour);
78  ASSERT_POINT_NEAR(contour.destination, Point(110, 100));
79  ASSERT_TRUE(contour.is_closed);
80  }
81 
82  {
83  Path path =
84  PathBuilder{}
85  .AddRoundedRect(Rect::MakeXYWH(100, 100, 100, 100), Size(10, 20))
86  .TakePath();
87  ContourComponent contour;
88  path.GetContourComponentAtIndex(0, contour);
89  ASSERT_POINT_NEAR(contour.destination, Point(110, 100));
90  ASSERT_TRUE(contour.is_closed);
91  }
92 
93  // Open shapes.
94  {
95  Point p(100, 100);
96  Path path = PathBuilder{}.AddLine(p, {200, 100}).TakePath();
97  ContourComponent contour;
98  path.GetContourComponentAtIndex(0, contour);
99  ASSERT_POINT_NEAR(contour.destination, p);
100  ASSERT_FALSE(contour.is_closed);
101  }
102 
103  {
104  Path path =
105  PathBuilder{}
106  .AddCubicCurve({100, 100}, {100, 50}, {100, 150}, {200, 100})
107  .TakePath();
108  ContourComponent contour;
109  path.GetContourComponentAtIndex(0, contour);
110  ASSERT_POINT_NEAR(contour.destination, Point(100, 100));
111  ASSERT_FALSE(contour.is_closed);
112  }
113 
114  {
115  Path path = PathBuilder{}
116  .AddQuadraticCurve({100, 100}, {100, 50}, {200, 100})
117  .TakePath();
118  ContourComponent contour;
119  path.GetContourComponentAtIndex(0, contour);
120  ASSERT_POINT_NEAR(contour.destination, Point(100, 100));
121  ASSERT_FALSE(contour.is_closed);
122  }
123 }

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, impeller::TRect< Scalar >::MakeXYWH(), and impeller::PathBuilder::TakePath().

◆ TEST() [228/370]

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

Definition at line 268 of file path_unittests.cc.

268  {
269  PathBuilder builder;
270  auto path_1 = builder.AddLine({0, 0}, {1, 1}).TakePath();
271 
272  ASSERT_EQ(path_1.GetBoundingBox().value_or(Rect::MakeMaximum()),
273  Rect::MakeLTRB(0, 0, 1, 1));
274 
275  auto path_2 = builder.AddLine({-1, -1}, {1, 1}).TakePath();
276 
277  // Verify that PathBuilder recomputes the bounds.
278  ASSERT_EQ(path_2.GetBoundingBox().value_or(Rect::MakeMaximum()),
279  Rect::MakeLTRB(-1, -1, 1, 1));
280 
281  // PathBuilder can set the bounds to whatever it wants
282  auto path_3 = builder.AddLine({0, 0}, {1, 1})
283  .SetBounds(Rect::MakeLTRB(0, 0, 100, 100))
284  .TakePath();
285 
286  ASSERT_EQ(path_3.GetBoundingBox().value_or(Rect::MakeMaximum()),
287  Rect::MakeLTRB(0, 0, 100, 100));
288 }

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

◆ TEST() [229/370]

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

Definition at line 25 of file path_unittests.cc.

25  {
26  PathBuilder builder;
27  builder.MoveTo({10, 10});
28  builder.LineTo({20, 20});
29  builder.LineTo({30, 30});
30  builder.MoveTo({40, 40});
31  builder.LineTo({50, 50});
32 
33  auto polyline = builder.TakePath().CreatePolyline(1.0f);
34 
35  ASSERT_EQ(polyline.contours.size(), 2u);
36  ASSERT_EQ(polyline.points->size(), 5u);
37  ASSERT_EQ(polyline.GetPoint(0).x, 10);
38  ASSERT_EQ(polyline.GetPoint(1).x, 20);
39  ASSERT_EQ(polyline.GetPoint(2).x, 30);
40  ASSERT_EQ(polyline.GetPoint(3).x, 40);
41  ASSERT_EQ(polyline.GetPoint(4).x, 50);
42 }

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

◆ TEST() [230/370]

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

Definition at line 125 of file path_unittests.cc.

125  {
126  Path::Polyline polyline = PathBuilder{}
127  .AddLine({100, 100}, {200, 100})
128  .MoveTo({100, 200})
129  .LineTo({150, 250})
130  .LineTo({200, 200})
131  .Close()
132  .TakePath()
133  .CreatePolyline(1.0f);
134  ASSERT_EQ(polyline.points->size(), 6u);
135  ASSERT_EQ(polyline.contours.size(), 2u);
136  ASSERT_EQ(polyline.contours[0].is_closed, false);
137  ASSERT_EQ(polyline.contours[0].start_index, 0u);
138  ASSERT_EQ(polyline.contours[1].is_closed, true);
139  ASSERT_EQ(polyline.contours[1].start_index, 2u);
140 }

References impeller::PathBuilder::AddLine(), impeller::Close(), impeller::LineTo(), impeller::MoveTo(), and polyline.

◆ TEST() [231/370]

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

Definition at line 372 of file path_unittests.cc.

372  {
373  PathBuilder builder;
374  // Straight diagonal line.
375  builder.AddCubicCurve({0, 1}, {2, 3}, {4, 5}, {6, 7});
376  auto path = builder.TakePath();
377  auto actual = path.GetBoundingBox();
378  auto expected = Rect::MakeLTRB(0, 1, 6, 7);
379 
380  ASSERT_TRUE(actual.has_value());
381  ASSERT_RECT_NEAR(actual.value_or(Rect::MakeMaximum()), expected);
382 }

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

◆ TEST() [232/370]

impeller::testing::TEST ( PathTest  ,
PathHorizontalLine   
)

Definition at line 290 of file path_unittests.cc.

290  {
291  PathBuilder builder;
292  auto path = builder.HorizontalLineTo(10).TakePath();
293 
294  LinearPathComponent linear;
295  path.GetLinearComponentAtIndex(1, linear);
296 
297  EXPECT_EQ(linear.p1, Point(0, 0));
298  EXPECT_EQ(linear.p2, Point(10, 0));
299 }

References impeller::PathBuilder::HorizontalLineTo(), impeller::LinearPathComponent::p1, impeller::LinearPathComponent::p2, and impeller::PathBuilder::TakePath().

◆ TEST() [233/370]

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

Definition at line 176 of file path_unittests.cc.

176  {
177  Path::Polyline polyline =
178  PathBuilder{}
179  .MoveTo({50, 50})
180  .LineTo({50, 50}) // Insert duplicate at beginning of contour.
181  .LineTo({100, 50})
182  .LineTo({100, 50}) // Insert duplicate at contour join.
183  .LineTo({100, 100})
184  .Close() // Implicitly insert duplicate {50, 50} across contours.
185  .LineTo({0, 50})
186  .LineTo({0, 100})
187  .LineTo({0, 100}) // Insert duplicate at end of contour.
188  .TakePath()
189  .CreatePolyline(1.0f);
190  ASSERT_EQ(polyline.contours.size(), 2u);
191  ASSERT_EQ(polyline.contours[0].start_index, 0u);
192  ASSERT_TRUE(polyline.contours[0].is_closed);
193  ASSERT_EQ(polyline.contours[1].start_index, 4u);
194  ASSERT_FALSE(polyline.contours[1].is_closed);
195  ASSERT_EQ(polyline.points->size(), 7u);
196  ASSERT_EQ(polyline.GetPoint(0), Point(50, 50));
197  ASSERT_EQ(polyline.GetPoint(1), Point(100, 50));
198  ASSERT_EQ(polyline.GetPoint(2), Point(100, 100));
199  ASSERT_EQ(polyline.GetPoint(3), Point(50, 50));
200  ASSERT_EQ(polyline.GetPoint(4), Point(50, 50));
201  ASSERT_EQ(polyline.GetPoint(5), Point(0, 50));
202  ASSERT_EQ(polyline.GetPoint(6), Point(0, 100));
203 }

References impeller::Close(), impeller::LineTo(), impeller::PathBuilder::MoveTo(), and polyline.

◆ TEST() [234/370]

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

Definition at line 232 of file path_unittests.cc.

232  {
233  PathBuilder builder{};
234  auto path =
235  builder.AddLine(Point(0, 0), Point(10, 10))
236  .AddQuadraticCurve(Point(10, 10), Point(15, 15), Point(20, 20))
237  .AddCubicCurve(Point(20, 20), Point(25, 25), Point(-5, -5),
238  Point(30, 30))
239  .Close()
240  .Shift(Point(1, 1))
241  .TakePath();
242 
243  ContourComponent contour;
244  LinearPathComponent linear;
245  QuadraticPathComponent quad;
246  CubicPathComponent cubic;
247 
248  ASSERT_TRUE(path.GetContourComponentAtIndex(0, contour));
249  ASSERT_TRUE(path.GetLinearComponentAtIndex(1, linear));
250  ASSERT_TRUE(path.GetQuadraticComponentAtIndex(3, quad));
251  ASSERT_TRUE(path.GetCubicComponentAtIndex(5, cubic));
252 
253  EXPECT_EQ(contour.destination, Point(1, 1));
254 
255  EXPECT_EQ(linear.p1, Point(1, 1));
256  EXPECT_EQ(linear.p2, Point(11, 11));
257 
258  EXPECT_EQ(quad.cp, Point(16, 16));
259  EXPECT_EQ(quad.p1, Point(11, 11));
260  EXPECT_EQ(quad.p2, Point(21, 21));
261 
262  EXPECT_EQ(cubic.cp1, Point(26, 26));
263  EXPECT_EQ(cubic.cp2, Point(-4, -4));
264  EXPECT_EQ(cubic.p1, Point(21, 21));
265  EXPECT_EQ(cubic.p2, Point(31, 31));
266 }

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

impeller::testing::TEST ( PathTest  ,
PathVerticalLine   
)

Definition at line 301 of file path_unittests.cc.

301  {
302  PathBuilder builder;
303  auto path = builder.VerticalLineTo(10).TakePath();
304 
305  LinearPathComponent linear;
306  path.GetLinearComponentAtIndex(1, linear);
307 
308  EXPECT_EQ(linear.p1, Point(0, 0));
309  EXPECT_EQ(linear.p2, Point(0, 10));
310 }

References impeller::LinearPathComponent::p1, impeller::LinearPathComponent::p2, impeller::PathBuilder::TakePath(), and impeller::PathBuilder::VerticalLineTo().

◆ TEST() [236/370]

impeller::testing::TEST ( PathTest  ,
PolylineBufferReuse   
)

Definition at line 205 of file path_unittests.cc.

205  {
206  auto point_buffer = std::make_unique<std::vector<Point>>();
207  auto point_buffer_address = reinterpret_cast<uintptr_t>(point_buffer.get());
208  Path::Polyline polyline =
209  PathBuilder{}
210  .MoveTo({50, 50})
211  .LineTo({100, 100})
212  .TakePath()
213  .CreatePolyline(
214  1.0f, std::move(point_buffer),
215  [point_buffer_address](
216  Path::Polyline::PointBufferPtr point_buffer) {
217  ASSERT_EQ(point_buffer->size(), 0u);
218  ASSERT_EQ(point_buffer_address,
219  reinterpret_cast<uintptr_t>(point_buffer.get()));
220  });
221 }

References impeller::LineTo(), impeller::PathBuilder::MoveTo(), and polyline.

◆ TEST() [237/370]

impeller::testing::TEST ( PathTest  ,
PolylineFailsWithNullptrBuffer   
)

Definition at line 223 of file path_unittests.cc.

223  {
224  EXPECT_DEATH_IF_SUPPORTED(PathBuilder{}
225  .MoveTo({50, 50})
226  .LineTo({100, 100})
227  .TakePath()
228  .CreatePolyline(1.0f, nullptr),
229  "");
230 }

References impeller::LineTo(), and impeller::PathBuilder::MoveTo().

◆ TEST() [238/370]

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

Definition at line 142 of file path_unittests.cc.

142  {
143  Path::Polyline polyline = PathBuilder{}
144  .AddLine({100, 100}, {200, 100})
145  .MoveTo({100, 200})
146  .LineTo({150, 250})
147  .LineTo({200, 200})
148  .Close()
149  .TakePath()
150  .CreatePolyline(1.0f);
151  size_t a1, a2, b1, b2;
152  std::tie(a1, a2) = polyline.GetContourPointBounds(0);
153  std::tie(b1, b2) = polyline.GetContourPointBounds(1);
154  ASSERT_EQ(a1, 0u);
155  ASSERT_EQ(a2, 2u);
156  ASSERT_EQ(b1, 2u);
157  ASSERT_EQ(b2, 6u);
158 }

References impeller::PathBuilder::AddLine(), impeller::Close(), impeller::LineTo(), impeller::MoveTo(), and polyline.

◆ TEST() [239/370]

impeller::testing::TEST ( PathTest  ,
QuadradicPath   
)

Definition at line 312 of file path_unittests.cc.

312  {
313  PathBuilder builder;
314  auto path = builder.QuadraticCurveTo(Point(10, 10), Point(20, 20)).TakePath();
315 
316  QuadraticPathComponent quad;
317  path.GetQuadraticComponentAtIndex(1, quad);
318 
319  EXPECT_EQ(quad.p1, Point(0, 0));
320  EXPECT_EQ(quad.cp, Point(10, 10));
321  EXPECT_EQ(quad.p2, Point(20, 20));
322 }

References impeller::QuadraticPathComponent::cp, impeller::QuadraticPathComponent::p1, impeller::QuadraticPathComponent::p2, impeller::PathBuilder::QuadraticCurveTo(), and impeller::PathBuilder::TakePath().

◆ TEST() [240/370]

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

Definition at line 397 of file path_unittests.cc.

397  {
398  PathBuilder builder;
399 
400  auto path = builder.AddLine({0, 0}, {100, 100})
401  .AddQuadraticCurve({100, 100}, {200, 200}, {300, 300})
402  .AddCubicCurve({300, 300}, {400, 400}, {500, 500}, {600, 600})
403  .TakePath();
404 
405  ASSERT_EQ(path.GetComponentCount(), 6u);
406  ASSERT_EQ(path.GetComponentCount(Path::ComponentType::kLinear), 1u);
407  ASSERT_EQ(path.GetComponentCount(Path::ComponentType::kQuadratic), 1u);
408  ASSERT_EQ(path.GetComponentCount(Path::ComponentType::kCubic), 1u);
409  ASSERT_EQ(path.GetComponentCount(Path::ComponentType::kContour), 3u);
410 
411  path.EnumerateComponents(
412  [](size_t index, const LinearPathComponent& linear) {
413  Point p1(0, 0);
414  Point p2(100, 100);
415  ASSERT_EQ(index, 1u);
416  ASSERT_EQ(linear.p1, p1);
417  ASSERT_EQ(linear.p2, p2);
418  },
419  [](size_t index, const QuadraticPathComponent& quad) {
420  Point p1(100, 100);
421  Point cp(200, 200);
422  Point p2(300, 300);
423  ASSERT_EQ(index, 3u);
424  ASSERT_EQ(quad.p1, p1);
425  ASSERT_EQ(quad.cp, cp);
426  ASSERT_EQ(quad.p2, p2);
427  },
428  [](size_t index, const CubicPathComponent& cubic) {
429  Point p1(300, 300);
430  Point cp1(400, 400);
431  Point cp2(500, 500);
432  Point p2(600, 600);
433  ASSERT_EQ(index, 5u);
434  ASSERT_EQ(cubic.p1, p1);
435  ASSERT_EQ(cubic.cp1, cp1);
436  ASSERT_EQ(cubic.cp2, cp2);
437  ASSERT_EQ(cubic.p2, p2);
438  },
439  [](size_t index, const ContourComponent& contour) {
440  // There is an initial countour added for each curve.
441  if (index == 0u) {
442  Point p1(0, 0);
443  ASSERT_EQ(contour.destination, p1);
444  } else if (index == 2u) {
445  Point p1(100, 100);
446  ASSERT_EQ(contour.destination, p1);
447  } else if (index == 4u) {
448  Point p1(300, 300);
449  ASSERT_EQ(contour.destination, p1);
450  } else {
451  ASSERT_FALSE(true);
452  }
453  ASSERT_FALSE(contour.is_closed);
454  });
455 }

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

◆ TEST() [241/370]

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

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  values.reserve(20);
52  for (int i = 0; i < 20; i++) {
53  values.push_back(pool.Grab());
54  }
55  for (const auto& value : values) {
56  value->SetSize(100);
57  pool.Recycle(value);
58  }
59  }
60  EXPECT_EQ(pool.GetSize(), 1'000u);
61 }

◆ TEST() [243/370]

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

impeller::testing::TEST ( RectTest  ,
ContainsFloatingPoint   
)

Definition at line 1271 of file rect_unittests.cc.

1271  {
1272  auto rect1 =
1273  Rect::MakeXYWH(472.599945f, 440.999969f, 1102.80005f, 654.000061f);
1274  auto rect2 = Rect::MakeXYWH(724.f, 618.f, 600.f, 300.f);
1275  EXPECT_TRUE(rect1.Contains(rect2));
1276 }

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

◆ TEST() [245/370]

impeller::testing::TEST ( RectTest  ,
EmptyIRectDoesNotIntersect   
)

Definition at line 854 of file rect_unittests.cc.

854  {
855  IRect rect = IRect::MakeLTRB(50, 50, 100, 100);
856 
857  auto test = [&rect](int64_t l, int64_t t, int64_t r, int64_t b,
858  const std::string& label) {
859  EXPECT_FALSE(IRect::MakeLTRB(l, b, r, t).IntersectsWithRect(rect))
860  << label << " with Top/Bottom swapped";
861  EXPECT_FALSE(IRect::MakeLTRB(r, b, l, t).IntersectsWithRect(rect))
862  << label << " with Left/Right swapped";
863  EXPECT_FALSE(IRect::MakeLTRB(r, t, l, b).IntersectsWithRect(rect))
864  << label << " with all sides swapped";
865  };
866 
867  test(20, 20, 30, 30, "Above and Left");
868  test(70, 20, 80, 30, "Above");
869  test(120, 20, 130, 30, "Above and Right");
870  test(120, 70, 130, 80, "Right");
871  test(120, 120, 130, 130, "Below and Right");
872  test(70, 120, 80, 130, "Below");
873  test(20, 120, 30, 130, "Below and Left");
874  test(20, 70, 30, 80, "Left");
875 
876  test(70, 70, 80, 80, "Inside");
877 
878  test(40, 70, 60, 80, "Straddling Left");
879  test(70, 40, 80, 60, "Straddling Top");
880  test(90, 70, 110, 80, "Straddling Right");
881  test(70, 90, 80, 110, "Straddling Bottom");
882 }

References impeller::saturated::b, and impeller::TRect< int64_t >::MakeLTRB().

◆ TEST() [246/370]

impeller::testing::TEST ( RectTest  ,
EmptyRectDoesNotIntersect   
)

Definition at line 824 of file rect_unittests.cc.

824  {
825  Rect rect = Rect::MakeLTRB(50, 50, 100, 100);
826 
827  auto test = [&rect](Scalar l, Scalar t, Scalar r, Scalar b,
828  const std::string& label) {
829  EXPECT_FALSE(Rect::MakeLTRB(l, b, r, t).IntersectsWithRect(rect))
830  << label << " with Top/Bottom swapped";
831  EXPECT_FALSE(Rect::MakeLTRB(r, b, l, t).IntersectsWithRect(rect))
832  << label << " with Left/Right swapped";
833  EXPECT_FALSE(Rect::MakeLTRB(r, t, l, b).IntersectsWithRect(rect))
834  << label << " with all sides swapped";
835  };
836 
837  test(20, 20, 30, 30, "Above and Left");
838  test(70, 20, 80, 30, "Above");
839  test(120, 20, 130, 30, "Above and Right");
840  test(120, 70, 130, 80, "Right");
841  test(120, 120, 130, 130, "Below and Right");
842  test(70, 120, 80, 130, "Below");
843  test(20, 120, 30, 130, "Below and Left");
844  test(20, 70, 30, 80, "Left");
845 
846  test(70, 70, 80, 80, "Inside");
847 
848  test(40, 70, 60, 80, "Straddling Left");
849  test(70, 40, 80, 60, "Straddling Top");
850  test(90, 70, 110, 80, "Straddling Right");
851  test(70, 90, 80, 110, "Straddling Bottom");
852 }

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

◆ TEST() [247/370]

impeller::testing::TEST ( RectTest  ,
GetCenter   
)

Definition at line 1194 of file rect_unittests.cc.

1194  {
1195  EXPECT_EQ(Rect::MakeXYWH(10, 30, 20, 20).GetCenter(), Point(20, 40));
1196  EXPECT_EQ(Rect::MakeXYWH(10, 30, 20, 19).GetCenter(), Point(20, 39.5));
1197  EXPECT_EQ(Rect::MakeMaximum().GetCenter(), Point(0, 0));
1198 
1199  // Note that we expect a Point as the answer from an IRect
1200  EXPECT_EQ(IRect::MakeXYWH(10, 30, 20, 20).GetCenter(), Point(20, 40));
1201  EXPECT_EQ(IRect::MakeXYWH(10, 30, 20, 19).GetCenter(), Point(20, 39.5));
1202  EXPECT_EQ(IRect::MakeMaximum().GetCenter(), Point(0, 0));
1203 }

References impeller::TRect< Scalar >::MakeMaximum(), impeller::TRect< int64_t >::MakeMaximum(), impeller::TRect< int64_t >::MakeXYWH(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [248/370]

impeller::testing::TEST ( RectTest  ,
IRectArea   
)

Definition at line 980 of file rect_unittests.cc.

980  {
981  EXPECT_EQ(IRect::MakeXYWH(0, 0, 100, 200).Area(), 20000);
982  EXPECT_EQ(IRect::MakeXYWH(10, 20, 100, 200).Area(), 20000);
983  EXPECT_EQ(IRect::MakeXYWH(0, 0, 200, 100).Area(), 20000);
984  EXPECT_EQ(IRect::MakeXYWH(10, 20, 200, 100).Area(), 20000);
985  EXPECT_EQ(IRect::MakeXYWH(0, 0, 100, 100).Area(), 10000);
986  EXPECT_EQ(IRect::MakeXYWH(10, 20, 100, 100).Area(), 10000);
987 }

References impeller::TRect< int64_t >::MakeXYWH().

◆ TEST() [249/370]

impeller::testing::TEST ( RectTest  ,
IRectContainsIPoint   
)

Definition at line 2193 of file rect_unittests.cc.

2193  {
2194  auto check_empty_flips = [](const IRect& rect, const IPoint& point,
2195  const std::string& label) {
2196  ASSERT_FALSE(rect.IsEmpty());
2197 
2198  EXPECT_FALSE(flip_lr(rect).Contains(point)) << label;
2199  EXPECT_FALSE(flip_tb(rect).Contains(point)) << label;
2200  EXPECT_FALSE(flip_lrtb(rect).Contains(point)) << label;
2201  };
2202 
2203  auto test_inside = [&check_empty_flips](const IRect& rect,
2204  const IPoint& point) {
2205  ASSERT_FALSE(rect.IsEmpty()) << rect;
2206 
2207  std::stringstream stream;
2208  stream << rect << " contains " << point;
2209  auto label = stream.str();
2210 
2211  EXPECT_TRUE(rect.Contains(point)) << label;
2212  check_empty_flips(rect, point, label);
2213  };
2214 
2215  auto test_outside = [&check_empty_flips](const IRect& rect,
2216  const IPoint& point) {
2217  ASSERT_FALSE(rect.IsEmpty()) << rect;
2218 
2219  std::stringstream stream;
2220  stream << rect << " contains " << point;
2221  auto label = stream.str();
2222 
2223  EXPECT_FALSE(rect.Contains(point)) << label;
2224  check_empty_flips(rect, point, label);
2225  };
2226 
2227  {
2228  // Origin is inclusive
2229  auto r = IRect::MakeXYWH(100, 100, 100, 100);
2230  auto p = IPoint(100, 100);
2231 
2232  test_inside(r, p);
2233  }
2234  {
2235  // Size is exclusive
2236  auto r = IRect::MakeXYWH(100, 100, 100, 100);
2237  auto p = IPoint(200, 200);
2238 
2239  test_outside(r, p);
2240  }
2241  {
2242  auto r = IRect::MakeXYWH(100, 100, 100, 100);
2243  auto p = IPoint(99, 99);
2244 
2245  test_outside(r, p);
2246  }
2247  {
2248  auto r = IRect::MakeXYWH(100, 100, 100, 100);
2249  auto p = IPoint(199, 199);
2250 
2251  test_inside(r, p);
2252  }
2253 
2254  {
2255  auto r = IRect::MakeMaximum();
2256  auto p = IPoint(199, 199);
2257 
2258  test_inside(r, p);
2259  }
2260 }

References impeller::TRect< T >::Contains(), flip_lr(), flip_lrtb(), flip_tb(), impeller::TRect< T >::IsEmpty(), impeller::TRect< int64_t >::MakeMaximum(), and impeller::TRect< int64_t >::MakeXYWH().

◆ TEST() [250/370]

impeller::testing::TEST ( RectTest  ,
IRectContainsIRect   
)

Definition at line 2377 of file rect_unittests.cc.

2377  {
2378  auto check_empty_flips = [](const IRect& a, const IRect& b,
2379  const std::string& label) {
2380  ASSERT_FALSE(a.IsEmpty());
2381  // test b rects are allowed to have 0 w/h, but not be backwards
2382  ASSERT_FALSE(b.GetLeft() > b.GetRight() || b.GetTop() > b.GetBottom());
2383 
2384  // unflipped a vs flipped (empty) b yields true
2385  EXPECT_TRUE(a.Contains(flip_lr(b))) << label;
2386  EXPECT_TRUE(a.Contains(flip_tb(b))) << label;
2387  EXPECT_TRUE(a.Contains(flip_lrtb(b))) << label;
2388 
2389  // flipped (empty) a vs unflipped b yields false
2390  EXPECT_FALSE(flip_lr(a).Contains(b)) << label;
2391  EXPECT_FALSE(flip_tb(a).Contains(b)) << label;
2392  EXPECT_FALSE(flip_lrtb(a).Contains(b)) << label;
2393 
2394  // flipped (empty) a vs flipped (empty) b yields empty
2395  EXPECT_FALSE(flip_lr(a).Contains(flip_lr(b))) << label;
2396  EXPECT_FALSE(flip_tb(a).Contains(flip_tb(b))) << label;
2397  EXPECT_FALSE(flip_lrtb(a).Contains(flip_lrtb(b))) << label;
2398  };
2399 
2400  auto test_inside = [&check_empty_flips](const IRect& a, const IRect& b) {
2401  ASSERT_FALSE(a.IsEmpty()) << a;
2402  // test b rects are allowed to have 0 w/h, but not be backwards
2403  ASSERT_FALSE(b.GetLeft() > b.GetRight() || b.GetTop() > b.GetBottom());
2404 
2405  std::stringstream stream;
2406  stream << a << " contains " << b;
2407  auto label = stream.str();
2408 
2409  EXPECT_TRUE(a.Contains(b)) << label;
2410  check_empty_flips(a, b, label);
2411  };
2412 
2413  auto test_not_inside = [&check_empty_flips](const IRect& a, const IRect& b) {
2414  ASSERT_FALSE(a.IsEmpty()) << a;
2415  // If b was empty, it would be contained and should not be tested with
2416  // this function - use |test_inside| instead.
2417  ASSERT_FALSE(b.IsEmpty()) << b;
2418 
2419  std::stringstream stream;
2420  stream << a << " contains " << b;
2421  auto label = stream.str();
2422 
2423  EXPECT_FALSE(a.Contains(b)) << label;
2424  check_empty_flips(a, b, label);
2425  };
2426 
2427  {
2428  auto a = IRect::MakeXYWH(100, 100, 100, 100);
2429 
2430  test_inside(a, a);
2431  }
2432  {
2433  auto a = IRect::MakeXYWH(100, 100, 100, 100);
2434  auto b = IRect::MakeXYWH(0, 0, 0, 0);
2435 
2436  test_inside(a, b);
2437  }
2438  {
2439  auto a = IRect::MakeXYWH(100, 100, 100, 100);
2440  auto b = IRect::MakeXYWH(150, 150, 20, 20);
2441 
2442  test_inside(a, b);
2443  }
2444  {
2445  auto a = IRect::MakeXYWH(100, 100, 100, 100);
2446  auto b = IRect::MakeXYWH(150, 150, 100, 100);
2447 
2448  test_not_inside(a, b);
2449  }
2450  {
2451  auto a = IRect::MakeXYWH(100, 100, 100, 100);
2452  auto b = IRect::MakeXYWH(50, 50, 100, 100);
2453 
2454  test_not_inside(a, b);
2455  }
2456  {
2457  auto a = IRect::MakeXYWH(100, 100, 100, 100);
2458  auto b = IRect::MakeXYWH(0, 0, 300, 300);
2459 
2460  test_not_inside(a, b);
2461  }
2462  {
2463  auto a = IRect::MakeMaximum();
2464  auto b = IRect::MakeXYWH(0, 0, 300, 300);
2465 
2466  test_inside(a, b);
2467  }
2468 }

References impeller::saturated::b, impeller::TRect< T >::Contains(), flip_lr(), flip_lrtb(), flip_tb(), impeller::TRect< T >::IsEmpty(), impeller::TRect< int64_t >::MakeMaximum(), and impeller::TRect< int64_t >::MakeXYWH().

◆ TEST() [251/370]

impeller::testing::TEST ( RectTest  ,
IRectCopy   
)

Definition at line 641 of file rect_unittests.cc.

641  {
642  IRect rect = IRect::MakeLTRB(5, 10, 20, 25);
643  IRect copy = rect;
644 
645  EXPECT_EQ(rect, copy);
646  EXPECT_EQ(copy.GetLeft(), 5);
647  EXPECT_EQ(copy.GetTop(), 10);
648  EXPECT_EQ(copy.GetRight(), 20);
649  EXPECT_EQ(copy.GetBottom(), 25);
650  EXPECT_EQ(copy.GetX(), 5);
651  EXPECT_EQ(copy.GetY(), 10);
652  EXPECT_EQ(copy.GetWidth(), 15);
653  EXPECT_EQ(copy.GetHeight(), 15);
654  EXPECT_FALSE(copy.IsEmpty());
655 }

References impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetTop(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetY(), impeller::TRect< T >::IsEmpty(), and impeller::TRect< int64_t >::MakeLTRB().

◆ TEST() [252/370]

impeller::testing::TEST ( RectTest  ,
IRectCutOut   
)

Definition at line 2622 of file rect_unittests.cc.

2622  {
2623  IRect cull_rect = IRect::MakeLTRB(20, 20, 40, 40);
2624 
2625  auto check_empty_flips = [&cull_rect](const IRect& diff_rect,
2626  const std::string& label) {
2627  EXPECT_FALSE(diff_rect.IsEmpty());
2628  EXPECT_FALSE(cull_rect.IsEmpty());
2629 
2630  // unflipped cull_rect vs flipped(empty) diff_rect
2631  // == cull_rect
2632  EXPECT_TRUE(cull_rect.Cutout(flip_lr(diff_rect)).has_value()) << label;
2633  EXPECT_EQ(cull_rect.Cutout(flip_lr(diff_rect)), cull_rect) << label;
2634  EXPECT_TRUE(cull_rect.Cutout(flip_tb(diff_rect)).has_value()) << label;
2635  EXPECT_EQ(cull_rect.Cutout(flip_tb(diff_rect)), cull_rect) << label;
2636  EXPECT_TRUE(cull_rect.Cutout(flip_lrtb(diff_rect)).has_value()) << label;
2637  EXPECT_EQ(cull_rect.Cutout(flip_lrtb(diff_rect)), cull_rect) << label;
2638 
2639  // flipped(empty) cull_rect vs flipped(empty) diff_rect
2640  // == empty
2641  EXPECT_FALSE(flip_lr(cull_rect).Cutout(diff_rect).has_value()) << label;
2642  EXPECT_EQ(flip_lr(cull_rect).CutoutOrEmpty(diff_rect), IRect()) << label;
2643  EXPECT_FALSE(flip_tb(cull_rect).Cutout(diff_rect).has_value()) << label;
2644  EXPECT_EQ(flip_tb(cull_rect).CutoutOrEmpty(diff_rect), IRect()) << label;
2645  EXPECT_FALSE(flip_lrtb(cull_rect).Cutout(diff_rect).has_value()) << label;
2646  EXPECT_EQ(flip_lrtb(cull_rect).CutoutOrEmpty(diff_rect), IRect()) << label;
2647 
2648  // flipped(empty) cull_rect vs unflipped diff_rect
2649  // == empty
2650  EXPECT_FALSE(flip_lr(cull_rect).Cutout(flip_lr(diff_rect)).has_value())
2651  << label;
2652  EXPECT_EQ(flip_lr(cull_rect).CutoutOrEmpty(flip_lr(diff_rect)), IRect())
2653  << label;
2654  EXPECT_FALSE(flip_tb(cull_rect).Cutout(flip_tb(diff_rect)).has_value())
2655  << label;
2656  EXPECT_EQ(flip_tb(cull_rect).CutoutOrEmpty(flip_tb(diff_rect)), IRect())
2657  << label;
2658  EXPECT_FALSE(flip_lrtb(cull_rect).Cutout(flip_lrtb(diff_rect)).has_value())
2659  << label;
2660  EXPECT_EQ(flip_lrtb(cull_rect).CutoutOrEmpty(flip_lrtb(diff_rect)), IRect())
2661  << label;
2662  };
2663 
2664  auto non_reducing = [&cull_rect, &check_empty_flips](
2665  const IRect& diff_rect, const std::string& label) {
2666  EXPECT_EQ(cull_rect.Cutout(diff_rect), cull_rect) << label;
2667  EXPECT_EQ(cull_rect.CutoutOrEmpty(diff_rect), cull_rect) << label;
2668  check_empty_flips(diff_rect, label);
2669  };
2670 
2671  auto reducing = [&cull_rect, &check_empty_flips](const IRect& diff_rect,
2672  const IRect& result_rect,
2673  const std::string& label) {
2674  EXPECT_TRUE(!result_rect.IsEmpty());
2675  EXPECT_EQ(cull_rect.Cutout(diff_rect), result_rect) << label;
2676  EXPECT_EQ(cull_rect.CutoutOrEmpty(diff_rect), result_rect) << label;
2677  check_empty_flips(diff_rect, label);
2678  };
2679 
2680  auto emptying = [&cull_rect, &check_empty_flips](const IRect& diff_rect,
2681  const std::string& label) {
2682  EXPECT_FALSE(cull_rect.Cutout(diff_rect).has_value()) << label;
2683  EXPECT_EQ(cull_rect.CutoutOrEmpty(diff_rect), IRect()) << label;
2684  check_empty_flips(diff_rect, label);
2685  };
2686 
2687  // Skim the corners and edge
2688  non_reducing(IRect::MakeLTRB(10, 10, 20, 20), "outside UL corner");
2689  non_reducing(IRect::MakeLTRB(20, 10, 40, 20), "Above");
2690  non_reducing(IRect::MakeLTRB(40, 10, 50, 20), "outside UR corner");
2691  non_reducing(IRect::MakeLTRB(40, 20, 50, 40), "Right");
2692  non_reducing(IRect::MakeLTRB(40, 40, 50, 50), "outside LR corner");
2693  non_reducing(IRect::MakeLTRB(20, 40, 40, 50), "Below");
2694  non_reducing(IRect::MakeLTRB(10, 40, 20, 50), "outside LR corner");
2695  non_reducing(IRect::MakeLTRB(10, 20, 20, 40), "Left");
2696 
2697  // Overlap corners
2698  non_reducing(IRect::MakeLTRB(15, 15, 25, 25), "covering UL corner");
2699  non_reducing(IRect::MakeLTRB(35, 15, 45, 25), "covering UR corner");
2700  non_reducing(IRect::MakeLTRB(35, 35, 45, 45), "covering LR corner");
2701  non_reducing(IRect::MakeLTRB(15, 35, 25, 45), "covering LL corner");
2702 
2703  // Overlap edges, but not across an entire side
2704  non_reducing(IRect::MakeLTRB(20, 15, 39, 25), "Top edge left-biased");
2705  non_reducing(IRect::MakeLTRB(21, 15, 40, 25), "Top edge, right biased");
2706  non_reducing(IRect::MakeLTRB(35, 20, 45, 39), "Right edge, top-biased");
2707  non_reducing(IRect::MakeLTRB(35, 21, 45, 40), "Right edge, bottom-biased");
2708  non_reducing(IRect::MakeLTRB(20, 35, 39, 45), "Bottom edge, left-biased");
2709  non_reducing(IRect::MakeLTRB(21, 35, 40, 45), "Bottom edge, right-biased");
2710  non_reducing(IRect::MakeLTRB(15, 20, 25, 39), "Left edge, top-biased");
2711  non_reducing(IRect::MakeLTRB(15, 21, 25, 40), "Left edge, bottom-biased");
2712 
2713  // Slice all the way through the middle
2714  non_reducing(IRect::MakeLTRB(25, 15, 35, 45), "Vertical interior slice");
2715  non_reducing(IRect::MakeLTRB(15, 25, 45, 35), "Horizontal interior slice");
2716 
2717  // Slice off each edge
2718  reducing(IRect::MakeLTRB(20, 15, 40, 25), //
2719  IRect::MakeLTRB(20, 25, 40, 40), //
2720  "Slice off top");
2721  reducing(IRect::MakeLTRB(35, 20, 45, 40), //
2722  IRect::MakeLTRB(20, 20, 35, 40), //
2723  "Slice off right");
2724  reducing(IRect::MakeLTRB(20, 35, 40, 45), //
2725  IRect::MakeLTRB(20, 20, 40, 35), //
2726  "Slice off bottom");
2727  reducing(IRect::MakeLTRB(15, 20, 25, 40), //
2728  IRect::MakeLTRB(25, 20, 40, 40), //
2729  "Slice off left");
2730 
2731  // cull rect contains diff rect
2732  non_reducing(IRect::MakeLTRB(21, 21, 39, 39), "Contained, non-covering");
2733 
2734  // cull rect equals diff rect
2735  emptying(cull_rect, "Perfectly covering");
2736 
2737  // diff rect contains cull rect
2738  emptying(IRect::MakeLTRB(15, 15, 45, 45), "Smothering");
2739 }

References impeller::TRect< T >::Cutout(), impeller::TRect< T >::CutoutOrEmpty(), flip_lr(), flip_lrtb(), flip_tb(), impeller::TRect< T >::IsEmpty(), and impeller::TRect< int64_t >::MakeLTRB().

◆ TEST() [253/370]

impeller::testing::TEST ( RectTest  ,
IRectDefaultConstructor   
)

Definition at line 59 of file rect_unittests.cc.

59  {
60  IRect rect = IRect();
61 
62  EXPECT_EQ(rect.GetLeft(), 0);
63  EXPECT_EQ(rect.GetTop(), 0);
64  EXPECT_EQ(rect.GetRight(), 0);
65  EXPECT_EQ(rect.GetBottom(), 0);
66  EXPECT_EQ(rect.GetX(), 0);
67  EXPECT_EQ(rect.GetY(), 0);
68  EXPECT_EQ(rect.GetWidth(), 0);
69  EXPECT_EQ(rect.GetHeight(), 0);
70  EXPECT_TRUE(rect.IsEmpty());
71 }

References impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetTop(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetY(), and impeller::TRect< T >::IsEmpty().

◆ TEST() [254/370]

impeller::testing::TEST ( RectTest  ,
IRectDoesNotIntersectEmpty   
)

Definition at line 794 of file rect_unittests.cc.

794  {
795  IRect rect = IRect::MakeLTRB(50, 50, 100, 100);
796 
797  auto test = [&rect](int64_t l, int64_t t, int64_t r, int64_t b,
798  const std::string& label) {
799  EXPECT_FALSE(rect.IntersectsWithRect(IRect::MakeLTRB(l, b, r, t)))
800  << label << " with Top/Bottom swapped";
801  EXPECT_FALSE(rect.IntersectsWithRect(IRect::MakeLTRB(r, b, l, t)))
802  << label << " with Left/Right swapped";
803  EXPECT_FALSE(rect.IntersectsWithRect(IRect::MakeLTRB(r, t, l, b)))
804  << label << " with all sides swapped";
805  };
806 
807  test(20, 20, 30, 30, "Above and Left");
808  test(70, 20, 80, 30, "Above");
809  test(120, 20, 130, 30, "Above and Right");
810  test(120, 70, 130, 80, "Right");
811  test(120, 120, 130, 130, "Below and Right");
812  test(70, 120, 80, 130, "Below");
813  test(20, 120, 30, 130, "Below and Left");
814  test(20, 70, 30, 80, "Left");
815 
816  test(70, 70, 80, 80, "Inside");
817 
818  test(40, 70, 60, 80, "Straddling Left");
819  test(70, 40, 80, 60, "Straddling Top");
820  test(90, 70, 110, 80, "Straddling Right");
821  test(70, 90, 80, 110, "Straddling Bottom");
822 }

References impeller::saturated::b, impeller::TRect< T >::IntersectsWithRect(), and impeller::TRect< int64_t >::MakeLTRB().

◆ TEST() [255/370]

impeller::testing::TEST ( RectTest  ,
IRectEmptyDeclaration   
)

Definition at line 29 of file rect_unittests.cc.

29  {
30  IRect rect;
31 
32  EXPECT_EQ(rect.GetLeft(), 0);
33  EXPECT_EQ(rect.GetTop(), 0);
34  EXPECT_EQ(rect.GetRight(), 0);
35  EXPECT_EQ(rect.GetBottom(), 0);
36  EXPECT_EQ(rect.GetX(), 0);
37  EXPECT_EQ(rect.GetY(), 0);
38  EXPECT_EQ(rect.GetWidth(), 0);
39  EXPECT_EQ(rect.GetHeight(), 0);
40  EXPECT_TRUE(rect.IsEmpty());
41  // EXPECT_TRUE(rect.IsFinite()); // should fail to compile
42 }

References impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetTop(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetY(), and impeller::TRect< T >::IsEmpty().

◆ TEST() [256/370]

impeller::testing::TEST ( RectTest  ,
IRectExpand   
)

Definition at line 1238 of file rect_unittests.cc.

1238  {
1239  auto rect = IRect::MakeLTRB(100, 100, 200, 200);
1240 
1241  // Expand(T amount)
1242  EXPECT_EQ(rect.Expand(10), IRect::MakeLTRB(90, 90, 210, 210));
1243  EXPECT_EQ(rect.Expand(-10), IRect::MakeLTRB(110, 110, 190, 190));
1244 
1245  // Expand(amount, amount)
1246  EXPECT_EQ(rect.Expand(10, 10), IRect::MakeLTRB(90, 90, 210, 210));
1247  EXPECT_EQ(rect.Expand(10, -10), IRect::MakeLTRB(90, 110, 210, 190));
1248  EXPECT_EQ(rect.Expand(-10, 10), IRect::MakeLTRB(110, 90, 190, 210));
1249  EXPECT_EQ(rect.Expand(-10, -10), IRect::MakeLTRB(110, 110, 190, 190));
1250 
1251  // Expand(amount, amount, amount, amount)
1252  EXPECT_EQ(rect.Expand(10, 20, 30, 40), IRect::MakeLTRB(90, 80, 230, 240));
1253  EXPECT_EQ(rect.Expand(-10, 20, 30, 40), IRect::MakeLTRB(110, 80, 230, 240));
1254  EXPECT_EQ(rect.Expand(10, -20, 30, 40), IRect::MakeLTRB(90, 120, 230, 240));
1255  EXPECT_EQ(rect.Expand(10, 20, -30, 40), IRect::MakeLTRB(90, 80, 170, 240));
1256  EXPECT_EQ(rect.Expand(10, 20, 30, -40), IRect::MakeLTRB(90, 80, 230, 160));
1257 
1258  // Expand(IPoint amount)
1259  EXPECT_EQ(rect.Expand(IPoint{10, 10}), IRect::MakeLTRB(90, 90, 210, 210));
1260  EXPECT_EQ(rect.Expand(IPoint{10, -10}), IRect::MakeLTRB(90, 110, 210, 190));
1261  EXPECT_EQ(rect.Expand(IPoint{-10, 10}), IRect::MakeLTRB(110, 90, 190, 210));
1262  EXPECT_EQ(rect.Expand(IPoint{-10, -10}), IRect::MakeLTRB(110, 110, 190, 190));
1263 
1264  // Expand(ISize amount)
1265  EXPECT_EQ(rect.Expand(ISize{10, 10}), IRect::MakeLTRB(90, 90, 210, 210));
1266  EXPECT_EQ(rect.Expand(ISize{10, -10}), IRect::MakeLTRB(90, 110, 210, 190));
1267  EXPECT_EQ(rect.Expand(ISize{-10, 10}), IRect::MakeLTRB(110, 90, 190, 210));
1268  EXPECT_EQ(rect.Expand(ISize{-10, -10}), IRect::MakeLTRB(110, 110, 190, 190));
1269 }

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

◆ TEST() [257/370]

impeller::testing::TEST ( RectTest  ,
IRectFromIRect   
)

Definition at line 616 of file rect_unittests.cc.

616  {
617  EXPECT_EQ(IRect(IRect::MakeXYWH(2, 3, 7, 15)), //
618  IRect::MakeXYWH(2, 3, 7, 15));
619  EXPECT_EQ(IRect(IRect::MakeLTRB(2, 3, 7, 15)), //
620  IRect::MakeLTRB(2, 3, 7, 15));
621 }

References impeller::TRect< int64_t >::MakeLTRB(), and impeller::TRect< int64_t >::MakeXYWH().

◆ TEST() [258/370]

impeller::testing::TEST ( RectTest  ,
IRectGetNormalizingTransform   
)

Definition at line 1077 of file rect_unittests.cc.

1077  {
1078  {
1079  // Checks for expected matrix values
1080 
1081  auto r = IRect::MakeXYWH(100, 200, 200, 400);
1082 
1083  EXPECT_EQ(r.GetNormalizingTransform(),
1084  Matrix::MakeScale({0.005, 0.0025, 1.0}) *
1085  Matrix::MakeTranslation({-100, -200}));
1086  }
1087 
1088  {
1089  // Checks for expected transform of points relative to the rect
1090 
1091  auto r = IRect::MakeLTRB(300, 500, 400, 700);
1092  auto m = r.GetNormalizingTransform();
1093 
1094  // The 4 corners of the rect => (0, 0) to (1, 1)
1095  EXPECT_EQ(m * Point(300, 500), Point(0, 0));
1096  EXPECT_EQ(m * Point(400, 500), Point(1, 0));
1097  EXPECT_EQ(m * Point(400, 700), Point(1, 1));
1098  EXPECT_EQ(m * Point(300, 700), Point(0, 1));
1099 
1100  // The center => (0.5, 0.5)
1101  EXPECT_EQ(m * Point(350, 600), Point(0.5, 0.5));
1102 
1103  // Outside the 4 corners => (-1, -1) to (2, 2)
1104  EXPECT_EQ(m * Point(200, 300), Point(-1, -1));
1105  EXPECT_EQ(m * Point(500, 300), Point(2, -1));
1106  EXPECT_EQ(m * Point(500, 900), Point(2, 2));
1107  EXPECT_EQ(m * Point(200, 900), Point(-1, 2));
1108  }
1109 
1110  {
1111  // Checks for behavior with empty rects
1112 
1113  auto zero = Matrix::MakeScale({0.0, 0.0, 1.0});
1114 
1115  // Empty for width and/or height == 0
1116  EXPECT_EQ(IRect::MakeXYWH(10, 10, 0, 10).GetNormalizingTransform(), zero);
1117  EXPECT_EQ(IRect::MakeXYWH(10, 10, 10, 0).GetNormalizingTransform(), zero);
1118  EXPECT_EQ(IRect::MakeXYWH(10, 10, 0, 0).GetNormalizingTransform(), zero);
1119 
1120  // Empty for width and/or height < 0
1121  EXPECT_EQ(IRect::MakeXYWH(10, 10, -1, 10).GetNormalizingTransform(), zero);
1122  EXPECT_EQ(IRect::MakeXYWH(10, 10, 10, -1).GetNormalizingTransform(), zero);
1123  EXPECT_EQ(IRect::MakeXYWH(10, 10, -1, -1).GetNormalizingTransform(), zero);
1124  }
1125 }

References impeller::TRect< int64_t >::MakeLTRB(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), and impeller::TRect< int64_t >::MakeXYWH().

◆ TEST() [259/370]

impeller::testing::TEST ( RectTest  ,
IRectIntersection   
)

Definition at line 1751 of file rect_unittests.cc.

1751  {
1752  auto check_empty_flips = [](const IRect& a, const IRect& b,
1753  const std::string& label) {
1754  ASSERT_FALSE(a.IsEmpty());
1755  // b is allowed to be empty
1756 
1757  // unflipped a vs flipped (empty) b yields a
1758  EXPECT_FALSE(a.Intersection(flip_lr(b)).has_value()) << label;
1759  EXPECT_FALSE(a.Intersection(flip_tb(b)).has_value()) << label;
1760  EXPECT_FALSE(a.Intersection(flip_lrtb(b)).has_value()) << label;
1761 
1762  // flipped (empty) a vs unflipped b yields b
1763  EXPECT_FALSE(flip_lr(a).Intersection(b).has_value()) << label;
1764  EXPECT_FALSE(flip_tb(a).Intersection(b).has_value()) << label;
1765  EXPECT_FALSE(flip_lrtb(a).Intersection(b).has_value()) << label;
1766 
1767  // flipped (empty) a vs flipped (empty) b yields empty
1768  EXPECT_FALSE(flip_lr(a).Intersection(flip_lr(b)).has_value()) << label;
1769  EXPECT_FALSE(flip_tb(a).Intersection(flip_tb(b)).has_value()) << label;
1770  EXPECT_FALSE(flip_lrtb(a).Intersection(flip_lrtb(b)).has_value()) << label;
1771  };
1772 
1773  auto test_non_empty = [&check_empty_flips](const IRect& a, const IRect& b,
1774  const IRect& result) {
1775  ASSERT_FALSE(a.IsEmpty()) << a;
1776  // b is allowed to be empty
1777 
1778  std::stringstream stream;
1779  stream << a << " union " << b;
1780  auto label = stream.str();
1781 
1782  EXPECT_TRUE(a.Intersection(b).has_value()) << label;
1783  EXPECT_TRUE(b.Intersection(a).has_value()) << label;
1784  EXPECT_EQ(a.Intersection(b), result) << label;
1785  EXPECT_EQ(b.Intersection(a), result) << label;
1786  check_empty_flips(a, b, label);
1787  };
1788 
1789  auto test_empty = [&check_empty_flips](const IRect& a, const IRect& b) {
1790  ASSERT_FALSE(a.IsEmpty()) << a;
1791  // b is allowed to be empty
1792 
1793  std::stringstream stream;
1794  stream << a << " union " << b;
1795  auto label = stream.str();
1796 
1797  EXPECT_FALSE(a.Intersection(b).has_value()) << label;
1798  EXPECT_FALSE(b.Intersection(a).has_value()) << label;
1799  check_empty_flips(a, b, label);
1800  };
1801 
1802  {
1803  auto a = IRect::MakeXYWH(100, 100, 100, 100);
1804  auto b = IRect::MakeXYWH(0, 0, 0, 0);
1805 
1806  test_empty(a, b);
1807  }
1808 
1809  {
1810  auto a = IRect::MakeXYWH(100, 100, 100, 100);
1811  auto b = IRect::MakeXYWH(10, 10, 0, 0);
1812 
1813  test_empty(a, b);
1814  }
1815 
1816  {
1817  auto a = IRect::MakeXYWH(0, 0, 100, 100);
1818  auto b = IRect::MakeXYWH(10, 10, 100, 100);
1819  auto expected = IRect::MakeXYWH(10, 10, 90, 90);
1820 
1821  test_non_empty(a, b, expected);
1822  }
1823 
1824  {
1825  auto a = IRect::MakeXYWH(0, 0, 100, 100);
1826  auto b = IRect::MakeXYWH(100, 100, 100, 100);
1827 
1828  test_empty(a, b);
1829  }
1830 
1831  {
1832  auto a = IRect::MakeMaximum();
1833  auto b = IRect::MakeXYWH(10, 10, 300, 300);
1834 
1835  test_non_empty(a, b, b);
1836  }
1837 
1838  {
1839  auto a = IRect::MakeMaximum();
1840  auto b = IRect::MakeMaximum();
1841 
1842  test_non_empty(a, b, IRect::MakeMaximum());
1843  }
1844 }

References impeller::saturated::b, flip_lr(), flip_lrtb(), flip_tb(), impeller::TRect< T >::Intersection(), impeller::TRect< T >::IsEmpty(), impeller::TRect< int64_t >::MakeMaximum(), and impeller::TRect< int64_t >::MakeXYWH().

◆ TEST() [260/370]

impeller::testing::TEST ( RectTest  ,
IRectIntersectsWithRect   
)

Definition at line 2016 of file rect_unittests.cc.

2016  {
2017  auto check_empty_flips = [](const IRect& a, const IRect& b,
2018  const std::string& label) {
2019  ASSERT_FALSE(a.IsEmpty());
2020  // b is allowed to be empty
2021 
2022  // unflipped a vs flipped (empty) b yields a
2023  EXPECT_FALSE(a.IntersectsWithRect(flip_lr(b))) << label;
2024  EXPECT_FALSE(a.IntersectsWithRect(flip_tb(b))) << label;
2025  EXPECT_FALSE(a.IntersectsWithRect(flip_lrtb(b))) << label;
2026 
2027  // flipped (empty) a vs unflipped b yields b
2028  EXPECT_FALSE(flip_lr(a).IntersectsWithRect(b)) << label;
2029  EXPECT_FALSE(flip_tb(a).IntersectsWithRect(b)) << label;
2030  EXPECT_FALSE(flip_lrtb(a).IntersectsWithRect(b)) << label;
2031 
2032  // flipped (empty) a vs flipped (empty) b yields empty
2033  EXPECT_FALSE(flip_lr(a).IntersectsWithRect(flip_lr(b))) << label;
2034  EXPECT_FALSE(flip_tb(a).IntersectsWithRect(flip_tb(b))) << label;
2035  EXPECT_FALSE(flip_lrtb(a).IntersectsWithRect(flip_lrtb(b))) << label;
2036  };
2037 
2038  auto test_non_empty = [&check_empty_flips](const IRect& a, const IRect& b) {
2039  ASSERT_FALSE(a.IsEmpty()) << a;
2040  // b is allowed to be empty
2041 
2042  std::stringstream stream;
2043  stream << a << " union " << b;
2044  auto label = stream.str();
2045 
2046  EXPECT_TRUE(a.IntersectsWithRect(b)) << label;
2047  EXPECT_TRUE(b.IntersectsWithRect(a)) << label;
2048  check_empty_flips(a, b, label);
2049  };
2050 
2051  auto test_empty = [&check_empty_flips](const IRect& a, const IRect& b) {
2052  ASSERT_FALSE(a.IsEmpty()) << a;
2053  // b is allowed to be empty
2054 
2055  std::stringstream stream;
2056  stream << a << " union " << b;
2057  auto label = stream.str();
2058 
2059  EXPECT_FALSE(a.IntersectsWithRect(b)) << label;
2060  EXPECT_FALSE(b.IntersectsWithRect(a)) << label;
2061  check_empty_flips(a, b, label);
2062  };
2063 
2064  {
2065  auto a = IRect::MakeXYWH(100, 100, 100, 100);
2066  auto b = IRect::MakeXYWH(0, 0, 0, 0);
2067 
2068  test_empty(a, b);
2069  }
2070 
2071  {
2072  auto a = IRect::MakeXYWH(100, 100, 100, 100);
2073  auto b = IRect::MakeXYWH(10, 10, 0, 0);
2074 
2075  test_empty(a, b);
2076  }
2077 
2078  {
2079  auto a = IRect::MakeXYWH(0, 0, 100, 100);
2080  auto b = IRect::MakeXYWH(10, 10, 100, 100);
2081 
2082  test_non_empty(a, b);
2083  }
2084 
2085  {
2086  auto a = IRect::MakeXYWH(0, 0, 100, 100);
2087  auto b = IRect::MakeXYWH(100, 100, 100, 100);
2088 
2089  test_empty(a, b);
2090  }
2091 
2092  {
2093  auto a = IRect::MakeMaximum();
2094  auto b = IRect::MakeXYWH(10, 10, 100, 100);
2095 
2096  test_non_empty(a, b);
2097  }
2098 
2099  {
2100  auto a = IRect::MakeMaximum();
2101  auto b = IRect::MakeMaximum();
2102 
2103  test_non_empty(a, b);
2104  }
2105 }

References impeller::saturated::b, flip_lr(), flip_lrtb(), flip_tb(), impeller::TRect< T >::IntersectsWithRect(), impeller::TRect< T >::IsEmpty(), impeller::TRect< int64_t >::MakeMaximum(), and impeller::TRect< int64_t >::MakeXYWH().

◆ TEST() [261/370]

impeller::testing::TEST ( RectTest  ,
IRectMakeMaximum   
)

Definition at line 593 of file rect_unittests.cc.

593  {
594  IRect rect = IRect::MakeMaximum();
595  auto min = std::numeric_limits<int64_t>::min();
596  auto max = std::numeric_limits<int64_t>::max();
597 
598  EXPECT_EQ(rect.GetLeft(), min);
599  EXPECT_EQ(rect.GetTop(), min);
600  EXPECT_EQ(rect.GetRight(), max);
601  EXPECT_EQ(rect.GetBottom(), max);
602  EXPECT_EQ(rect.GetX(), min);
603  EXPECT_EQ(rect.GetY(), min);
604  EXPECT_EQ(rect.GetWidth(), max);
605  EXPECT_EQ(rect.GetHeight(), max);
606  EXPECT_FALSE(rect.IsEmpty());
607 }

References impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetTop(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetY(), impeller::TRect< T >::IsEmpty(), and impeller::TRect< int64_t >::MakeMaximum().

◆ TEST() [262/370]

impeller::testing::TEST ( RectTest  ,
IRectOriginSizeXYWHGetters   
)

Definition at line 683 of file rect_unittests.cc.

683  {
684  {
685  IRect r = IRect::MakeOriginSize({10, 20}, {50, 40});
686  EXPECT_EQ(r.GetOrigin(), IPoint(10, 20));
687  EXPECT_EQ(r.GetSize(), ISize(50, 40));
688  EXPECT_EQ(r.GetX(), 10);
689  EXPECT_EQ(r.GetY(), 20);
690  EXPECT_EQ(r.GetWidth(), 50);
691  EXPECT_EQ(r.GetHeight(), 40);
692  auto expected_array = std::array<int64_t, 4>{10, 20, 50, 40};
693  EXPECT_EQ(r.GetXYWH(), expected_array);
694  }
695 
696  {
697  IRect r = IRect::MakeLTRB(10, 20, 50, 40);
698  EXPECT_EQ(r.GetOrigin(), IPoint(10, 20));
699  EXPECT_EQ(r.GetSize(), ISize(40, 20));
700  EXPECT_EQ(r.GetX(), 10);
701  EXPECT_EQ(r.GetY(), 20);
702  EXPECT_EQ(r.GetWidth(), 40);
703  EXPECT_EQ(r.GetHeight(), 20);
704  auto expected_array = std::array<int64_t, 4>{10, 20, 40, 20};
705  EXPECT_EQ(r.GetXYWH(), expected_array);
706  }
707 }

References impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetOrigin(), impeller::TRect< T >::GetSize(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetXYWH(), impeller::TRect< T >::GetY(), impeller::TRect< int64_t >::MakeLTRB(), and impeller::TRect< int64_t >::MakeOriginSize().

◆ TEST() [263/370]

impeller::testing::TEST ( RectTest  ,
IRectOverflowLTRB   
)

Definition at line 478 of file rect_unittests.cc.

478  {
479  auto min = std::numeric_limits<int64_t>::min();
480  auto max = std::numeric_limits<int64_t>::max();
481 
482  // 4 cases
483  // negative l, r near max takes width past max
484  // positive l, r near min takes width below min
485  // negative t, b near max takes width past max
486  // positive t, b near min takes width below min
487 
488  {
489  IRect rect = IRect::MakeLTRB(-10, 10, max - 5, 26);
490 
491  EXPECT_EQ(rect.GetLeft(), -10);
492  EXPECT_EQ(rect.GetTop(), 10);
493  EXPECT_EQ(rect.GetRight(), max - 5);
494  EXPECT_EQ(rect.GetBottom(), 26);
495  EXPECT_EQ(rect.GetX(), -10);
496  EXPECT_EQ(rect.GetY(), 10);
497  EXPECT_EQ(rect.GetWidth(), max);
498  EXPECT_EQ(rect.GetHeight(), 16);
499  EXPECT_FALSE(rect.IsEmpty());
500  }
501 
502  {
503  IRect rect = IRect::MakeLTRB(10, 10, min + 5, 26);
504 
505  EXPECT_EQ(rect.GetLeft(), 10);
506  EXPECT_EQ(rect.GetTop(), 10);
507  EXPECT_EQ(rect.GetRight(), min + 5);
508  EXPECT_EQ(rect.GetBottom(), 26);
509  EXPECT_EQ(rect.GetX(), 10);
510  EXPECT_EQ(rect.GetY(), 10);
511  EXPECT_EQ(rect.GetWidth(), min);
512  EXPECT_EQ(rect.GetHeight(), 16);
513  EXPECT_TRUE(rect.IsEmpty());
514  }
515 
516  {
517  IRect rect = IRect::MakeLTRB(5, -10, 15, max - 5);
518 
519  EXPECT_EQ(rect.GetLeft(), 5);
520  EXPECT_EQ(rect.GetTop(), -10);
521  EXPECT_EQ(rect.GetRight(), 15);
522  EXPECT_EQ(rect.GetBottom(), max - 5);
523  EXPECT_EQ(rect.GetX(), 5);
524  EXPECT_EQ(rect.GetY(), -10);
525  EXPECT_EQ(rect.GetWidth(), 10);
526  EXPECT_EQ(rect.GetHeight(), max);
527  EXPECT_FALSE(rect.IsEmpty());
528  }
529 
530  {
531  IRect rect = IRect::MakeLTRB(5, 10, 15, min + 5);
532 
533  EXPECT_EQ(rect.GetLeft(), 5);
534  EXPECT_EQ(rect.GetTop(), 10);
535  EXPECT_EQ(rect.GetRight(), 15);
536  EXPECT_EQ(rect.GetBottom(), min + 5);
537  EXPECT_EQ(rect.GetX(), 5);
538  EXPECT_EQ(rect.GetY(), 10);
539  EXPECT_EQ(rect.GetWidth(), 10);
540  EXPECT_EQ(rect.GetHeight(), min);
541  EXPECT_TRUE(rect.IsEmpty());
542  }
543 }

References impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetTop(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetY(), impeller::TRect< T >::IsEmpty(), and impeller::TRect< int64_t >::MakeLTRB().

◆ TEST() [264/370]

impeller::testing::TEST ( RectTest  ,
IRectOverflowXYWH   
)

Definition at line 272 of file rect_unittests.cc.

272  {
273  auto min = std::numeric_limits<int64_t>::min();
274  auto max = std::numeric_limits<int64_t>::max();
275 
276  // 4 cases
277  // x near max, positive w takes it past max
278  // x near min, negative w takes it below min
279  // y near max, positive h takes it past max
280  // y near min, negative h takes it below min
281 
282  {
283  IRect rect = IRect::MakeXYWH(max - 5, 10, 10, 16);
284 
285  EXPECT_EQ(rect.GetLeft(), max - 5);
286  EXPECT_EQ(rect.GetTop(), 10);
287  EXPECT_EQ(rect.GetRight(), max);
288  EXPECT_EQ(rect.GetBottom(), 26);
289  EXPECT_EQ(rect.GetX(), max - 5);
290  EXPECT_EQ(rect.GetY(), 10);
291  EXPECT_EQ(rect.GetWidth(), 5);
292  EXPECT_EQ(rect.GetHeight(), 16);
293  EXPECT_FALSE(rect.IsEmpty());
294  }
295 
296  {
297  IRect rect = IRect::MakeXYWH(min + 5, 10, -10, 16);
298 
299  EXPECT_EQ(rect.GetLeft(), min + 5);
300  EXPECT_EQ(rect.GetTop(), 10);
301  EXPECT_EQ(rect.GetRight(), min);
302  EXPECT_EQ(rect.GetBottom(), 26);
303  EXPECT_EQ(rect.GetX(), min + 5);
304  EXPECT_EQ(rect.GetY(), 10);
305  EXPECT_EQ(rect.GetWidth(), -5);
306  EXPECT_EQ(rect.GetHeight(), 16);
307  EXPECT_TRUE(rect.IsEmpty());
308  }
309 
310  {
311  IRect rect = IRect::MakeXYWH(5, max - 10, 10, 16);
312 
313  EXPECT_EQ(rect.GetLeft(), 5);
314  EXPECT_EQ(rect.GetTop(), max - 10);
315  EXPECT_EQ(rect.GetRight(), 15);
316  EXPECT_EQ(rect.GetBottom(), max);
317  EXPECT_EQ(rect.GetX(), 5);
318  EXPECT_EQ(rect.GetY(), max - 10);
319  EXPECT_EQ(rect.GetWidth(), 10);
320  EXPECT_EQ(rect.GetHeight(), 10);
321  EXPECT_FALSE(rect.IsEmpty());
322  }
323 
324  {
325  IRect rect = IRect::MakeXYWH(5, min + 10, 10, -16);
326 
327  EXPECT_EQ(rect.GetLeft(), 5);
328  EXPECT_EQ(rect.GetTop(), min + 10);
329  EXPECT_EQ(rect.GetRight(), 15);
330  EXPECT_EQ(rect.GetBottom(), min);
331  EXPECT_EQ(rect.GetX(), 5);
332  EXPECT_EQ(rect.GetY(), min + 10);
333  EXPECT_EQ(rect.GetWidth(), 10);
334  EXPECT_EQ(rect.GetHeight(), -10);
335  EXPECT_TRUE(rect.IsEmpty());
336  }
337 }

References impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetTop(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetY(), impeller::TRect< T >::IsEmpty(), and impeller::TRect< int64_t >::MakeXYWH().

◆ TEST() [265/370]

impeller::testing::TEST ( RectTest  ,
IRectRoundOut   
)

Definition at line 2852 of file rect_unittests.cc.

2852  {
2853  {
2854  auto r = Rect::MakeLTRB(-100, -100, 100, 100);
2855  auto ir = IRect::MakeLTRB(-100, -100, 100, 100);
2856  EXPECT_EQ(IRect::RoundOut(r), ir);
2857  }
2858  {
2859  auto r = Rect::MakeLTRB(-100.1, -100.1, 100.1, 100.1);
2860  auto ir = IRect::MakeLTRB(-101, -101, 101, 101);
2861  EXPECT_EQ(IRect::RoundOut(r), ir);
2862  }
2863 }

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

◆ TEST() [266/370]

impeller::testing::TEST ( RectTest  ,
IRectScale   
)

Definition at line 929 of file rect_unittests.cc.

929  {
930  auto test1 = [](IRect rect, int64_t scale) {
931  IRect expected = IRect::MakeXYWH(rect.GetX() * scale, //
932  rect.GetY() * scale, //
933  rect.GetWidth() * scale, //
934  rect.GetHeight() * scale);
935 
936  EXPECT_EQ(rect.Scale(scale), expected) //
937  << rect << " * " << scale;
938  EXPECT_EQ(rect.Scale(scale, scale), expected) //
939  << rect << " * " << scale;
940  EXPECT_EQ(rect.Scale(IPoint(scale, scale)), expected) //
941  << rect << " * " << scale;
942  EXPECT_EQ(rect.Scale(ISize(scale, scale)), expected) //
943  << rect << " * " << scale;
944  };
945 
946  auto test2 = [&test1](IRect rect, int64_t scale_x, int64_t scale_y) {
947  IRect expected = IRect::MakeXYWH(rect.GetX() * scale_x, //
948  rect.GetY() * scale_y, //
949  rect.GetWidth() * scale_x, //
950  rect.GetHeight() * scale_y);
951 
952  EXPECT_EQ(rect.Scale(scale_x, scale_y), expected) //
953  << rect << " * " << scale_x << ", " << scale_y;
954  EXPECT_EQ(rect.Scale(IPoint(scale_x, scale_y)), expected) //
955  << rect << " * " << scale_x << ", " << scale_y;
956  EXPECT_EQ(rect.Scale(ISize(scale_x, scale_y)), expected) //
957  << rect << " * " << scale_x << ", " << scale_y;
958 
959  test1(rect, scale_x);
960  test1(rect, scale_y);
961  };
962 
963  test2(IRect::MakeLTRB(10, 15, 100, 150), 2, 3);
964  test2(IRect::MakeLTRB(10, 15, 100, 150), 3, 2);
965  test2(IRect::MakeLTRB(10, 15, -100, 150), 2, 3);
966  test2(IRect::MakeLTRB(10, 15, 100, -150), 2, 3);
967  test2(IRect::MakeLTRB(10, 15, 100, 150), -2, 3);
968  test2(IRect::MakeLTRB(10, 15, 100, 150), 2, -3);
969 }

References impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetY(), impeller::TRect< int64_t >::MakeLTRB(), impeller::TRect< int64_t >::MakeXYWH(), impeller::TRect< T >::Scale(), and scale.

◆ TEST() [267/370]

impeller::testing::TEST ( RectTest  ,
IRectSimpleLTRB   
)

Definition at line 89 of file rect_unittests.cc.

89  {
90  IRect rect = IRect::MakeLTRB(5, 10, 20, 25);
91 
92  EXPECT_EQ(rect.GetLeft(), 5);
93  EXPECT_EQ(rect.GetTop(), 10);
94  EXPECT_EQ(rect.GetRight(), 20);
95  EXPECT_EQ(rect.GetBottom(), 25);
96  EXPECT_EQ(rect.GetX(), 5);
97  EXPECT_EQ(rect.GetY(), 10);
98  EXPECT_EQ(rect.GetWidth(), 15);
99  EXPECT_EQ(rect.GetHeight(), 15);
100  EXPECT_FALSE(rect.IsEmpty());
101 }

References impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetTop(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetY(), impeller::TRect< T >::IsEmpty(), and impeller::TRect< int64_t >::MakeLTRB().

◆ TEST() [268/370]

impeller::testing::TEST ( RectTest  ,
IRectSimpleXYWH   
)

Definition at line 119 of file rect_unittests.cc.

119  {
120  IRect rect = IRect::MakeXYWH(5, 10, 15, 16);
121 
122  EXPECT_EQ(rect.GetLeft(), 5);
123  EXPECT_EQ(rect.GetTop(), 10);
124  EXPECT_EQ(rect.GetRight(), 20);
125  EXPECT_EQ(rect.GetBottom(), 26);
126  EXPECT_EQ(rect.GetX(), 5);
127  EXPECT_EQ(rect.GetY(), 10);
128  EXPECT_EQ(rect.GetWidth(), 15);
129  EXPECT_EQ(rect.GetHeight(), 16);
130  EXPECT_FALSE(rect.IsEmpty());
131 }

References impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetTop(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetY(), impeller::TRect< T >::IsEmpty(), and impeller::TRect< int64_t >::MakeXYWH().

◆ TEST() [269/370]

impeller::testing::TEST ( RectTest  ,
IRectUnion   
)

Definition at line 1456 of file rect_unittests.cc.

1456  {
1457  auto check_empty_flips = [](const IRect& a, const IRect& b,
1458  const std::string& label) {
1459  ASSERT_FALSE(a.IsEmpty());
1460  // b is allowed to be empty
1461 
1462  // unflipped a vs flipped (empty) b yields a
1463  EXPECT_EQ(a.Union(flip_lr(b)), a) << label;
1464  EXPECT_EQ(a.Union(flip_tb(b)), a) << label;
1465  EXPECT_EQ(a.Union(flip_lrtb(b)), a) << label;
1466 
1467  // flipped (empty) a vs unflipped b yields b
1468  EXPECT_EQ(flip_lr(a).Union(b), b) << label;
1469  EXPECT_EQ(flip_tb(a).Union(b), b) << label;
1470  EXPECT_EQ(flip_lrtb(a).Union(b), b) << label;
1471 
1472  // flipped (empty) a vs flipped (empty) b yields empty
1473  EXPECT_TRUE(flip_lr(a).Union(flip_lr(b)).IsEmpty()) << label;
1474  EXPECT_TRUE(flip_tb(a).Union(flip_tb(b)).IsEmpty()) << label;
1475  EXPECT_TRUE(flip_lrtb(a).Union(flip_lrtb(b)).IsEmpty()) << label;
1476  };
1477 
1478  auto test = [&check_empty_flips](const IRect& a, const IRect& b,
1479  const IRect& result) {
1480  ASSERT_FALSE(a.IsEmpty()) << a;
1481  // b is allowed to be empty
1482 
1483  std::stringstream stream;
1484  stream << a << " union " << b;
1485  auto label = stream.str();
1486 
1487  EXPECT_EQ(a.Union(b), result) << label;
1488  EXPECT_EQ(b.Union(a), result) << label;
1489  check_empty_flips(a, b, label);
1490  };
1491 
1492  {
1493  auto a = IRect::MakeXYWH(100, 100, 100, 100);
1494  auto b = IRect::MakeXYWH(0, 0, 0, 0);
1495  auto expected = IRect::MakeXYWH(100, 100, 100, 100);
1496  test(a, b, expected);
1497  }
1498 
1499  {
1500  auto a = IRect::MakeXYWH(100, 100, 100, 100);
1501  auto b = IRect::MakeXYWH(0, 0, 1, 1);
1502  auto expected = IRect::MakeXYWH(0, 0, 200, 200);
1503  test(a, b, expected);
1504  }
1505 
1506  {
1507  auto a = IRect::MakeXYWH(100, 100, 100, 100);
1508  auto b = IRect::MakeXYWH(10, 10, 1, 1);
1509  auto expected = IRect::MakeXYWH(10, 10, 190, 190);
1510  test(a, b, expected);
1511  }
1512 
1513  {
1514  auto a = IRect::MakeXYWH(0, 0, 100, 100);
1515  auto b = IRect::MakeXYWH(10, 10, 100, 100);
1516  auto expected = IRect::MakeXYWH(0, 0, 110, 110);
1517  test(a, b, expected);
1518  }
1519 
1520  {
1521  auto a = IRect::MakeXYWH(0, 0, 100, 100);
1522  auto b = IRect::MakeXYWH(100, 100, 100, 100);
1523  auto expected = IRect::MakeXYWH(0, 0, 200, 200);
1524  test(a, b, expected);
1525  }
1526 }

References impeller::saturated::b, flip_lr(), flip_lrtb(), flip_tb(), impeller::TRect< T >::IsEmpty(), impeller::TRect< int64_t >::MakeXYWH(), and impeller::TRect< T >::Union().

◆ TEST() [270/370]

impeller::testing::TEST ( RectTest  ,
IRectXYWHIsEmpty   
)

Definition at line 1151 of file rect_unittests.cc.

1151  {
1152  // Non-empty
1153  EXPECT_FALSE(IRect::MakeXYWH(1, 2, 10, 7).IsEmpty());
1154 
1155  // Empty both width and height both 0 or negative, in all combinations
1156  EXPECT_TRUE(IRect::MakeXYWH(1, 2, 0, 0).IsEmpty());
1157  EXPECT_TRUE(IRect::MakeXYWH(1, 2, -1, -1).IsEmpty());
1158  EXPECT_TRUE(IRect::MakeXYWH(1, 2, -1, 0).IsEmpty());
1159  EXPECT_TRUE(IRect::MakeXYWH(1, 2, 0, -1).IsEmpty());
1160 
1161  // Empty for 0 or negative width or height (but not both at the same time)
1162  EXPECT_TRUE(IRect::MakeXYWH(1, 2, 10, 0).IsEmpty());
1163  EXPECT_TRUE(IRect::MakeXYWH(1, 2, 10, -1).IsEmpty());
1164  EXPECT_TRUE(IRect::MakeXYWH(1, 2, 0, 7).IsEmpty());
1165  EXPECT_TRUE(IRect::MakeXYWH(1, 2, -1, 7).IsEmpty());
1166 }

References impeller::TRect< int64_t >::MakeXYWH().

◆ TEST() [271/370]

impeller::testing::TEST ( RectTest  ,
IsSquare   
)

Definition at line 1182 of file rect_unittests.cc.

1182  {
1183  EXPECT_TRUE(Rect::MakeXYWH(10, 30, 20, 20).IsSquare());
1184  EXPECT_FALSE(Rect::MakeXYWH(10, 30, 20, 19).IsSquare());
1185  EXPECT_FALSE(Rect::MakeXYWH(10, 30, 19, 20).IsSquare());
1186  EXPECT_TRUE(Rect::MakeMaximum().IsSquare());
1187 
1188  EXPECT_TRUE(IRect::MakeXYWH(10, 30, 20, 20).IsSquare());
1189  EXPECT_FALSE(IRect::MakeXYWH(10, 30, 20, 19).IsSquare());
1190  EXPECT_FALSE(IRect::MakeXYWH(10, 30, 19, 20).IsSquare());
1191  EXPECT_TRUE(IRect::MakeMaximum().IsSquare());
1192 }

References impeller::TRect< Scalar >::MakeMaximum(), impeller::TRect< int64_t >::MakeMaximum(), impeller::TRect< int64_t >::MakeXYWH(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [272/370]

impeller::testing::TEST ( RectTest  ,
MakePointBoundsQuad   
)

Definition at line 1168 of file rect_unittests.cc.

1168  {
1169  Quad quad = {
1170  Point(10, 10),
1171  Point(20, 10),
1172  Point(10, 20),
1173  Point(20, 20),
1174  };
1175  std::optional<Rect> bounds = Rect::MakePointBounds(quad);
1176  EXPECT_TRUE(bounds.has_value());
1177  if (bounds.has_value()) {
1178  EXPECT_TRUE(RectNear(bounds.value(), Rect::MakeLTRB(10, 10, 20, 20)));
1179  }
1180 }

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

◆ TEST() [273/370]

impeller::testing::TEST ( RectTest  ,
OptIRectIntersection   
)

Definition at line 1846 of file rect_unittests.cc.

1846  {
1847  auto a = IRect::MakeLTRB(0, 0, 110, 110);
1848  auto b = IRect::MakeLTRB(100, 100, 200, 200);
1849  auto c = IRect::MakeLTRB(100, 0, 200, 110);
1850 
1851  // NullOpt, NullOpt
1852  EXPECT_FALSE(IRect::Intersection(std::nullopt, std::nullopt).has_value());
1853  EXPECT_EQ(IRect::Intersection(std::nullopt, std::nullopt), std::nullopt);
1854 
1855  auto test1 = [](const IRect& r) {
1856  // Rect, NullOpt
1857  EXPECT_TRUE(IRect::Intersection(r, std::nullopt).has_value());
1858  EXPECT_EQ(IRect::Intersection(r, std::nullopt).value(), r);
1859 
1860  // OptRect, NullOpt
1861  EXPECT_TRUE(
1862  IRect::Intersection(std::optional(r), std::nullopt).has_value());
1863  EXPECT_EQ(IRect::Intersection(std::optional(r), std::nullopt).value(), r);
1864 
1865  // NullOpt, Rect
1866  EXPECT_TRUE(IRect::Intersection(std::nullopt, r).has_value());
1867  EXPECT_EQ(IRect::Intersection(std::nullopt, r).value(), r);
1868 
1869  // NullOpt, OptRect
1870  EXPECT_TRUE(
1871  IRect::Intersection(std::nullopt, std::optional(r)).has_value());
1872  EXPECT_EQ(IRect::Intersection(std::nullopt, std::optional(r)).value(), r);
1873  };
1874 
1875  test1(a);
1876  test1(b);
1877  test1(c);
1878 
1879  auto test2 = [](const IRect& a, const IRect& b, const IRect& i) {
1880  ASSERT_EQ(a.Intersection(b), i);
1881 
1882  // Rect, OptRect
1883  EXPECT_TRUE(IRect::Intersection(a, std::optional(b)).has_value());
1884  EXPECT_EQ(IRect::Intersection(a, std::optional(b)).value(), i);
1885 
1886  // OptRect, Rect
1887  EXPECT_TRUE(IRect::Intersection(std::optional(a), b).has_value());
1888  EXPECT_EQ(IRect::Intersection(std::optional(a), b).value(), i);
1889 
1890  // OptRect, OptRect
1891  EXPECT_TRUE(
1892  IRect::Intersection(std::optional(a), std::optional(b)).has_value());
1893  EXPECT_EQ(IRect::Intersection(std::optional(a), std::optional(b)).value(),
1894  i);
1895  };
1896 
1897  test2(a, b, IRect::MakeLTRB(100, 100, 110, 110));
1898  test2(a, c, IRect::MakeLTRB(100, 0, 110, 110));
1899  test2(b, c, IRect::MakeLTRB(100, 100, 200, 110));
1900 }

References impeller::saturated::b, impeller::TRect< T >::Intersection(), impeller::TRect< int64_t >::Intersection(), and impeller::TRect< int64_t >::MakeLTRB().

◆ TEST() [274/370]

impeller::testing::TEST ( RectTest  ,
OptIRectUnion   
)

Definition at line 1528 of file rect_unittests.cc.

1528  {
1529  auto a = IRect::MakeLTRB(0, 0, 100, 100);
1530  auto b = IRect::MakeLTRB(100, 100, 200, 200);
1531  auto c = IRect::MakeLTRB(100, 0, 200, 100);
1532 
1533  // NullOpt, NullOpt
1534  EXPECT_FALSE(IRect::Union(std::nullopt, std::nullopt).has_value());
1535  EXPECT_EQ(IRect::Union(std::nullopt, std::nullopt), std::nullopt);
1536 
1537  auto test1 = [](const IRect& r) {
1538  // Rect, NullOpt
1539  EXPECT_TRUE(IRect::Union(r, std::nullopt).has_value());
1540  EXPECT_EQ(IRect::Union(r, std::nullopt).value(), r);
1541 
1542  // OptRect, NullOpt
1543  EXPECT_TRUE(IRect::Union(std::optional(r), std::nullopt).has_value());
1544  EXPECT_EQ(IRect::Union(std::optional(r), std::nullopt).value(), r);
1545 
1546  // NullOpt, Rect
1547  EXPECT_TRUE(IRect::Union(std::nullopt, r).has_value());
1548  EXPECT_EQ(IRect::Union(std::nullopt, r).value(), r);
1549 
1550  // NullOpt, OptRect
1551  EXPECT_TRUE(IRect::Union(std::nullopt, std::optional(r)).has_value());
1552  EXPECT_EQ(IRect::Union(std::nullopt, std::optional(r)).value(), r);
1553  };
1554 
1555  test1(a);
1556  test1(b);
1557  test1(c);
1558 
1559  auto test2 = [](const IRect& a, const IRect& b, const IRect& u) {
1560  ASSERT_EQ(a.Union(b), u);
1561 
1562  // Rect, OptRect
1563  EXPECT_TRUE(IRect::Union(a, std::optional(b)).has_value());
1564  EXPECT_EQ(IRect::Union(a, std::optional(b)).value(), u);
1565 
1566  // OptRect, Rect
1567  EXPECT_TRUE(IRect::Union(std::optional(a), b).has_value());
1568  EXPECT_EQ(IRect::Union(std::optional(a), b).value(), u);
1569 
1570  // OptRect, OptRect
1571  EXPECT_TRUE(IRect::Union(std::optional(a), std::optional(b)).has_value());
1572  EXPECT_EQ(IRect::Union(std::optional(a), std::optional(b)).value(), u);
1573  };
1574 
1575  test2(a, b, IRect::MakeLTRB(0, 0, 200, 200));
1576  test2(a, c, IRect::MakeLTRB(0, 0, 200, 100));
1577  test2(b, c, IRect::MakeLTRB(100, 0, 200, 200));
1578 }

References impeller::saturated::b, impeller::TRect< int64_t >::MakeLTRB(), impeller::TRect< int64_t >::Union(), and impeller::TRect< T >::Union().

◆ TEST() [275/370]

impeller::testing::TEST ( RectTest  ,
OptRectIntersection   
)

Definition at line 1697 of file rect_unittests.cc.

1697  {
1698  auto a = Rect::MakeLTRB(0, 0, 110, 110);
1699  auto b = Rect::MakeLTRB(100, 100, 200, 200);
1700  auto c = Rect::MakeLTRB(100, 0, 200, 110);
1701 
1702  // NullOpt, NullOpt
1703  EXPECT_FALSE(Rect::Intersection(std::nullopt, std::nullopt).has_value());
1704  EXPECT_EQ(Rect::Intersection(std::nullopt, std::nullopt), std::nullopt);
1705 
1706  auto test1 = [](const Rect& r) {
1707  // Rect, NullOpt
1708  EXPECT_TRUE(Rect::Intersection(r, std::nullopt).has_value());
1709  EXPECT_EQ(Rect::Intersection(r, std::nullopt).value(), r);
1710 
1711  // OptRect, NullOpt
1712  EXPECT_TRUE(Rect::Intersection(std::optional(r), std::nullopt).has_value());
1713  EXPECT_EQ(Rect::Intersection(std::optional(r), std::nullopt).value(), r);
1714 
1715  // NullOpt, Rect
1716  EXPECT_TRUE(Rect::Intersection(std::nullopt, r).has_value());
1717  EXPECT_EQ(Rect::Intersection(std::nullopt, r).value(), r);
1718 
1719  // NullOpt, OptRect
1720  EXPECT_TRUE(Rect::Intersection(std::nullopt, std::optional(r)).has_value());
1721  EXPECT_EQ(Rect::Intersection(std::nullopt, std::optional(r)).value(), r);
1722  };
1723 
1724  test1(a);
1725  test1(b);
1726  test1(c);
1727 
1728  auto test2 = [](const Rect& a, const Rect& b, const Rect& i) {
1729  ASSERT_EQ(a.Intersection(b), i);
1730 
1731  // Rect, OptRect
1732  EXPECT_TRUE(Rect::Intersection(a, std::optional(b)).has_value());
1733  EXPECT_EQ(Rect::Intersection(a, std::optional(b)).value(), i);
1734 
1735  // OptRect, Rect
1736  EXPECT_TRUE(Rect::Intersection(std::optional(a), b).has_value());
1737  EXPECT_EQ(Rect::Intersection(std::optional(a), b).value(), i);
1738 
1739  // OptRect, OptRect
1740  EXPECT_TRUE(
1741  Rect::Intersection(std::optional(a), std::optional(b)).has_value());
1742  EXPECT_EQ(Rect::Intersection(std::optional(a), std::optional(b)).value(),
1743  i);
1744  };
1745 
1746  test2(a, b, Rect::MakeLTRB(100, 100, 110, 110));
1747  test2(a, c, Rect::MakeLTRB(100, 0, 110, 110));
1748  test2(b, c, Rect::MakeLTRB(100, 100, 200, 110));
1749 }

References impeller::saturated::b, impeller::TRect< T >::Intersection(), impeller::TRect< Scalar >::Intersection(), and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST() [276/370]

impeller::testing::TEST ( RectTest  ,
OptRectUnion   
)

Definition at line 1404 of file rect_unittests.cc.

1404  {
1405  auto a = Rect::MakeLTRB(0, 0, 100, 100);
1406  auto b = Rect::MakeLTRB(100, 100, 200, 200);
1407  auto c = Rect::MakeLTRB(100, 0, 200, 100);
1408 
1409  // NullOpt, NullOpt
1410  EXPECT_FALSE(Rect::Union(std::nullopt, std::nullopt).has_value());
1411  EXPECT_EQ(Rect::Union(std::nullopt, std::nullopt), std::nullopt);
1412 
1413  auto test1 = [](const Rect& r) {
1414  // Rect, NullOpt
1415  EXPECT_TRUE(Rect::Union(r, std::nullopt).has_value());
1416  EXPECT_EQ(Rect::Union(r, std::nullopt).value(), r);
1417 
1418  // OptRect, NullOpt
1419  EXPECT_TRUE(Rect::Union(std::optional(r), std::nullopt).has_value());
1420  EXPECT_EQ(Rect::Union(std::optional(r), std::nullopt).value(), r);
1421 
1422  // NullOpt, Rect
1423  EXPECT_TRUE(Rect::Union(std::nullopt, r).has_value());
1424  EXPECT_EQ(Rect::Union(std::nullopt, r).value(), r);
1425 
1426  // NullOpt, OptRect
1427  EXPECT_TRUE(Rect::Union(std::nullopt, std::optional(r)).has_value());
1428  EXPECT_EQ(Rect::Union(std::nullopt, std::optional(r)).value(), r);
1429  };
1430 
1431  test1(a);
1432  test1(b);
1433  test1(c);
1434 
1435  auto test2 = [](const Rect& a, const Rect& b, const Rect& u) {
1436  ASSERT_EQ(a.Union(b), u);
1437 
1438  // Rect, OptRect
1439  EXPECT_TRUE(Rect::Union(a, std::optional(b)).has_value());
1440  EXPECT_EQ(Rect::Union(a, std::optional(b)).value(), u);
1441 
1442  // OptRect, Rect
1443  EXPECT_TRUE(Rect::Union(std::optional(a), b).has_value());
1444  EXPECT_EQ(Rect::Union(std::optional(a), b).value(), u);
1445 
1446  // OptRect, OptRect
1447  EXPECT_TRUE(Rect::Union(std::optional(a), std::optional(b)).has_value());
1448  EXPECT_EQ(Rect::Union(std::optional(a), std::optional(b)).value(), u);
1449  };
1450 
1451  test2(a, b, Rect::MakeLTRB(0, 0, 200, 200));
1452  test2(a, c, Rect::MakeLTRB(0, 0, 200, 100));
1453  test2(b, c, Rect::MakeLTRB(100, 0, 200, 200));
1454 }

References impeller::saturated::b, impeller::TRect< Scalar >::MakeLTRB(), impeller::TRect< Scalar >::Union(), and impeller::TRect< T >::Union().

◆ TEST() [277/370]

impeller::testing::TEST ( RectTest  ,
RectArea   
)

Definition at line 971 of file rect_unittests.cc.

971  {
972  EXPECT_EQ(Rect::MakeXYWH(0, 0, 100, 200).Area(), 20000);
973  EXPECT_EQ(Rect::MakeXYWH(10, 20, 100, 200).Area(), 20000);
974  EXPECT_EQ(Rect::MakeXYWH(0, 0, 200, 100).Area(), 20000);
975  EXPECT_EQ(Rect::MakeXYWH(10, 20, 200, 100).Area(), 20000);
976  EXPECT_EQ(Rect::MakeXYWH(0, 0, 100, 100).Area(), 10000);
977  EXPECT_EQ(Rect::MakeXYWH(10, 20, 100, 100).Area(), 10000);
978 }

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

◆ TEST() [278/370]

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

Definition at line 2107 of file rect_unittests.cc.

2107  {
2108  auto check_nans = [](const Rect& rect, const Point& point,
2109  const std::string& label) {
2110  ASSERT_TRUE(rect.IsFinite()) << label;
2111  ASSERT_TRUE(point.IsFinite()) << label;
2112 
2113  for (int i = 1; i < 16; i++) {
2114  EXPECT_FALSE(swap_nan(rect, i).Contains(point))
2115  << label << ", index = " << i;
2116  for (int j = 1; j < 4; j++) {
2117  EXPECT_FALSE(swap_nan(rect, i).Contains(swap_nan(point, j)))
2118  << label << ", indices = " << i << ", " << j;
2119  }
2120  }
2121  };
2122 
2123  auto check_empty_flips = [](const Rect& rect, const Point& point,
2124  const std::string& label) {
2125  ASSERT_FALSE(rect.IsEmpty());
2126 
2127  EXPECT_FALSE(flip_lr(rect).Contains(point)) << label;
2128  EXPECT_FALSE(flip_tb(rect).Contains(point)) << label;
2129  EXPECT_FALSE(flip_lrtb(rect).Contains(point)) << label;
2130  };
2131 
2132  auto test_inside = [&check_nans, &check_empty_flips](const Rect& rect,
2133  const Point& point) {
2134  ASSERT_FALSE(rect.IsEmpty()) << rect;
2135 
2136  std::stringstream stream;
2137  stream << rect << " contains " << point;
2138  auto label = stream.str();
2139 
2140  EXPECT_TRUE(rect.Contains(point)) << label;
2141  check_empty_flips(rect, point, label);
2142  check_nans(rect, point, label);
2143  };
2144 
2145  auto test_outside = [&check_nans, &check_empty_flips](const Rect& rect,
2146  const Point& point) {
2147  ASSERT_FALSE(rect.IsEmpty()) << rect;
2148 
2149  std::stringstream stream;
2150  stream << rect << " contains " << point;
2151  auto label = stream.str();
2152 
2153  EXPECT_FALSE(rect.Contains(point)) << label;
2154  check_empty_flips(rect, point, label);
2155  check_nans(rect, point, label);
2156  };
2157 
2158  {
2159  // Origin is inclusive
2160  auto r = Rect::MakeXYWH(100, 100, 100, 100);
2161  auto p = Point(100, 100);
2162 
2163  test_inside(r, p);
2164  }
2165  {
2166  // Size is exclusive
2167  auto r = Rect::MakeXYWH(100, 100, 100, 100);
2168  auto p = Point(200, 200);
2169 
2170  test_outside(r, p);
2171  }
2172  {
2173  auto r = Rect::MakeXYWH(100, 100, 100, 100);
2174  auto p = Point(99, 99);
2175 
2176  test_outside(r, p);
2177  }
2178  {
2179  auto r = Rect::MakeXYWH(100, 100, 100, 100);
2180  auto p = Point(199, 199);
2181 
2182  test_inside(r, p);
2183  }
2184 
2185  {
2186  auto r = Rect::MakeMaximum();
2187  auto p = Point(199, 199);
2188 
2189  test_inside(r, p);
2190  }
2191 }

References flip_lr(), flip_lrtb(), flip_tb(), impeller::TRect< T >::IsEmpty(), impeller::TRect< T >::IsFinite(), impeller::TRect< Scalar >::MakeMaximum(), impeller::TRect< Scalar >::MakeXYWH(), and swap_nan().

◆ TEST() [279/370]

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

Definition at line 2262 of file rect_unittests.cc.

2262  {
2263  auto check_nans = [](const Rect& a, const Rect& b, const std::string& label) {
2264  ASSERT_TRUE(a.IsFinite()) << label;
2265  ASSERT_TRUE(b.IsFinite()) << label;
2266  ASSERT_FALSE(a.IsEmpty());
2267 
2268  for (int i = 1; i < 16; i++) {
2269  // NaN in a produces false
2270  EXPECT_FALSE(swap_nan(a, i).Contains(b)) << label << ", index = " << i;
2271  // NaN in b produces false
2272  EXPECT_TRUE(a.Contains(swap_nan(b, i))) << label << ", index = " << i;
2273  // NaN in both is false
2274  for (int j = 1; j < 16; j++) {
2275  EXPECT_FALSE(swap_nan(a, i).Contains(swap_nan(b, j)))
2276  << label << ", indices = " << i << ", " << j;
2277  }
2278  }
2279  };
2280 
2281  auto check_empty_flips = [](const Rect& a, const Rect& b,
2282  const std::string& label) {
2283  ASSERT_FALSE(a.IsEmpty());
2284  // test b rects are allowed to have 0 w/h, but not be backwards
2285  ASSERT_FALSE(b.GetLeft() > b.GetRight() || b.GetTop() > b.GetBottom());
2286 
2287  // unflipped a vs flipped (empty) b yields false
2288  EXPECT_TRUE(a.Contains(flip_lr(b))) << label;
2289  EXPECT_TRUE(a.Contains(flip_tb(b))) << label;
2290  EXPECT_TRUE(a.Contains(flip_lrtb(b))) << label;
2291 
2292  // flipped (empty) a vs unflipped b yields false
2293  EXPECT_FALSE(flip_lr(a).Contains(b)) << label;
2294  EXPECT_FALSE(flip_tb(a).Contains(b)) << label;
2295  EXPECT_FALSE(flip_lrtb(a).Contains(b)) << label;
2296 
2297  // flipped (empty) a vs flipped (empty) b yields empty
2298  EXPECT_FALSE(flip_lr(a).Contains(flip_lr(b))) << label;
2299  EXPECT_FALSE(flip_tb(a).Contains(flip_tb(b))) << label;
2300  EXPECT_FALSE(flip_lrtb(a).Contains(flip_lrtb(b))) << label;
2301  };
2302 
2303  auto test_inside = [&check_nans, &check_empty_flips](const Rect& a,
2304  const Rect& b) {
2305  ASSERT_FALSE(a.IsEmpty()) << a;
2306  // test b rects are allowed to have 0 w/h, but not be backwards
2307  ASSERT_FALSE(b.GetLeft() > b.GetRight() || b.GetTop() > b.GetBottom());
2308 
2309  std::stringstream stream;
2310  stream << a << " contains " << b;
2311  auto label = stream.str();
2312 
2313  EXPECT_TRUE(a.Contains(b)) << label;
2314  check_empty_flips(a, b, label);
2315  check_nans(a, b, label);
2316  };
2317 
2318  auto test_not_inside = [&check_nans, &check_empty_flips](const Rect& a,
2319  const Rect& b) {
2320  ASSERT_FALSE(a.IsEmpty()) << a;
2321  // If b was empty, it would be contained and should not be tested with
2322  // this function - use |test_inside| instead.
2323  ASSERT_FALSE(b.IsEmpty()) << b;
2324 
2325  std::stringstream stream;
2326  stream << a << " contains " << b;
2327  auto label = stream.str();
2328 
2329  EXPECT_FALSE(a.Contains(b)) << label;
2330  check_empty_flips(a, b, label);
2331  check_nans(a, b, label);
2332  };
2333 
2334  {
2335  auto a = Rect::MakeXYWH(100, 100, 100, 100);
2336 
2337  test_inside(a, a);
2338  }
2339  {
2340  auto a = Rect::MakeXYWH(100, 100, 100, 100);
2341  auto b = Rect::MakeXYWH(0, 0, 0, 0);
2342 
2343  test_inside(a, b);
2344  }
2345  {
2346  auto a = Rect::MakeXYWH(100, 100, 100, 100);
2347  auto b = Rect::MakeXYWH(150, 150, 20, 20);
2348 
2349  test_inside(a, b);
2350  }
2351  {
2352  auto a = Rect::MakeXYWH(100, 100, 100, 100);
2353  auto b = Rect::MakeXYWH(150, 150, 100, 100);
2354 
2355  test_not_inside(a, b);
2356  }
2357  {
2358  auto a = Rect::MakeXYWH(100, 100, 100, 100);
2359  auto b = Rect::MakeXYWH(50, 50, 100, 100);
2360 
2361  test_not_inside(a, b);
2362  }
2363  {
2364  auto a = Rect::MakeXYWH(100, 100, 100, 100);
2365  auto b = Rect::MakeXYWH(0, 0, 300, 300);
2366 
2367  test_not_inside(a, b);
2368  }
2369  {
2370  auto a = Rect::MakeMaximum();
2371  auto b = Rect::MakeXYWH(0, 0, 300, 300);
2372 
2373  test_inside(a, b);
2374  }
2375 }

References impeller::saturated::b, impeller::TRect< T >::Contains(), flip_lr(), flip_lrtb(), flip_tb(), impeller::TRect< T >::IsEmpty(), impeller::TRect< T >::IsFinite(), impeller::TRect< Scalar >::MakeMaximum(), impeller::TRect< Scalar >::MakeXYWH(), and swap_nan().

◆ TEST() [280/370]

impeller::testing::TEST ( RectTest  ,
RectCopy   
)

Definition at line 623 of file rect_unittests.cc.

623  {
624  // Using fractional-power-of-2 friendly values for equality tests
625  Rect rect = Rect::MakeLTRB(5.125f, 10.25f, 20.625f, 25.375f);
626  Rect copy = rect;
627 
628  EXPECT_EQ(rect, copy);
629  EXPECT_EQ(copy.GetLeft(), 5.125f);
630  EXPECT_EQ(copy.GetTop(), 10.25f);
631  EXPECT_EQ(copy.GetRight(), 20.625f);
632  EXPECT_EQ(copy.GetBottom(), 25.375f);
633  EXPECT_EQ(copy.GetX(), 5.125f);
634  EXPECT_EQ(copy.GetY(), 10.25f);
635  EXPECT_EQ(copy.GetWidth(), 15.5f);
636  EXPECT_EQ(copy.GetHeight(), 15.125f);
637  EXPECT_FALSE(copy.IsEmpty());
638  EXPECT_TRUE(copy.IsFinite());
639 }

References impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetTop(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetY(), impeller::TRect< T >::IsEmpty(), impeller::TRect< T >::IsFinite(), and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST() [281/370]

impeller::testing::TEST ( RectTest  ,
RectCutOut   
)

Definition at line 2470 of file rect_unittests.cc.

2470  {
2471  Rect cull_rect = Rect::MakeLTRB(20, 20, 40, 40);
2472 
2473  auto check_nans = [&cull_rect](const Rect& diff_rect,
2474  const std::string& label) {
2475  EXPECT_TRUE(cull_rect.IsFinite()) << label;
2476  EXPECT_TRUE(diff_rect.IsFinite()) << label;
2477 
2478  for (int i = 1; i < 16; i++) {
2479  // NaN in cull_rect produces empty
2480  EXPECT_FALSE(swap_nan(cull_rect, i).Cutout(diff_rect).has_value())
2481  << label << ", index " << i;
2482  EXPECT_EQ(swap_nan(cull_rect, i).CutoutOrEmpty(diff_rect), Rect())
2483  << label << ", index " << i;
2484 
2485  // NaN in diff_rect is nop
2486  EXPECT_TRUE(cull_rect.Cutout(swap_nan(diff_rect, i)).has_value())
2487  << label << ", index " << i;
2488  EXPECT_EQ(cull_rect.CutoutOrEmpty(swap_nan(diff_rect, i)), cull_rect)
2489  << label << ", index " << i;
2490 
2491  for (int j = 1; j < 16; j++) {
2492  // NaN in both is also empty
2493  EXPECT_FALSE(
2494  swap_nan(cull_rect, i).Cutout(swap_nan(diff_rect, j)).has_value())
2495  << label << ", indices " << i << ", " << j;
2496  EXPECT_EQ(swap_nan(cull_rect, i).CutoutOrEmpty(swap_nan(diff_rect, j)),
2497  Rect())
2498  << label << ", indices " << i << ", " << j;
2499  }
2500  }
2501  };
2502 
2503  auto check_empty_flips = [&cull_rect](const Rect& diff_rect,
2504  const std::string& label) {
2505  EXPECT_FALSE(cull_rect.IsEmpty()) << label;
2506  EXPECT_FALSE(diff_rect.IsEmpty()) << label;
2507 
2508  // unflipped cull_rect vs flipped(empty) diff_rect
2509  // == cull_rect
2510  EXPECT_TRUE(cull_rect.Cutout(flip_lr(diff_rect)).has_value()) << label;
2511  EXPECT_EQ(cull_rect.Cutout(flip_lr(diff_rect)), cull_rect) << label;
2512  EXPECT_TRUE(cull_rect.Cutout(flip_tb(diff_rect)).has_value()) << label;
2513  EXPECT_EQ(cull_rect.Cutout(flip_tb(diff_rect)), cull_rect) << label;
2514  EXPECT_TRUE(cull_rect.Cutout(flip_lrtb(diff_rect)).has_value()) << label;
2515  EXPECT_EQ(cull_rect.Cutout(flip_lrtb(diff_rect)), cull_rect) << label;
2516 
2517  // flipped(empty) cull_rect vs unflipped diff_rect
2518  // == empty
2519  EXPECT_FALSE(flip_lr(cull_rect).Cutout(diff_rect).has_value()) << label;
2520  EXPECT_EQ(flip_lr(cull_rect).CutoutOrEmpty(diff_rect), Rect()) << label;
2521  EXPECT_FALSE(flip_tb(cull_rect).Cutout(diff_rect).has_value()) << label;
2522  EXPECT_EQ(flip_tb(cull_rect).CutoutOrEmpty(diff_rect), Rect()) << label;
2523  EXPECT_FALSE(flip_lrtb(cull_rect).Cutout(diff_rect).has_value()) << label;
2524  EXPECT_EQ(flip_lrtb(cull_rect).CutoutOrEmpty(diff_rect), Rect()) << label;
2525 
2526  // flipped(empty) cull_rect vs flipped(empty) diff_rect
2527  // == empty
2528  EXPECT_FALSE(flip_lr(cull_rect).Cutout(flip_lr(diff_rect)).has_value())
2529  << label;
2530  EXPECT_EQ(flip_lr(cull_rect).CutoutOrEmpty(flip_lr(diff_rect)), Rect())
2531  << label;
2532  EXPECT_FALSE(flip_tb(cull_rect).Cutout(flip_tb(diff_rect)).has_value())
2533  << label;
2534  EXPECT_EQ(flip_tb(cull_rect).CutoutOrEmpty(flip_tb(diff_rect)), Rect())
2535  << label;
2536  EXPECT_FALSE(flip_lrtb(cull_rect).Cutout(flip_lrtb(diff_rect)).has_value())
2537  << label;
2538  EXPECT_EQ(flip_lrtb(cull_rect).CutoutOrEmpty(flip_lrtb(diff_rect)), Rect())
2539  << label;
2540  };
2541 
2542  auto non_reducing = [&cull_rect, &check_empty_flips, &check_nans](
2543  const Rect& diff_rect, const std::string& label) {
2544  EXPECT_EQ(cull_rect.Cutout(diff_rect), cull_rect) << label;
2545  EXPECT_EQ(cull_rect.CutoutOrEmpty(diff_rect), cull_rect) << label;
2546  check_empty_flips(diff_rect, label);
2547  check_nans(diff_rect, label);
2548  };
2549 
2550  auto reducing = [&cull_rect, &check_empty_flips, &check_nans](
2551  const Rect& diff_rect, const Rect& result_rect,
2552  const std::string& label) {
2553  EXPECT_TRUE(!result_rect.IsEmpty());
2554  EXPECT_EQ(cull_rect.Cutout(diff_rect), result_rect) << label;
2555  EXPECT_EQ(cull_rect.CutoutOrEmpty(diff_rect), result_rect) << label;
2556  check_empty_flips(diff_rect, label);
2557  check_nans(diff_rect, label);
2558  };
2559 
2560  auto emptying = [&cull_rect, &check_empty_flips, &check_nans](
2561  const Rect& diff_rect, const std::string& label) {
2562  EXPECT_FALSE(cull_rect.Cutout(diff_rect).has_value()) << label;
2563  EXPECT_EQ(cull_rect.CutoutOrEmpty(diff_rect), Rect()) << label;
2564  check_empty_flips(diff_rect, label);
2565  check_nans(diff_rect, label);
2566  };
2567 
2568  // Skim the corners and edge
2569  non_reducing(Rect::MakeLTRB(10, 10, 20, 20), "outside UL corner");
2570  non_reducing(Rect::MakeLTRB(20, 10, 40, 20), "Above");
2571  non_reducing(Rect::MakeLTRB(40, 10, 50, 20), "outside UR corner");
2572  non_reducing(Rect::MakeLTRB(40, 20, 50, 40), "Right");
2573  non_reducing(Rect::MakeLTRB(40, 40, 50, 50), "outside LR corner");
2574  non_reducing(Rect::MakeLTRB(20, 40, 40, 50), "Below");
2575  non_reducing(Rect::MakeLTRB(10, 40, 20, 50), "outside LR corner");
2576  non_reducing(Rect::MakeLTRB(10, 20, 20, 40), "Left");
2577 
2578  // Overlap corners
2579  non_reducing(Rect::MakeLTRB(15, 15, 25, 25), "covering UL corner");
2580  non_reducing(Rect::MakeLTRB(35, 15, 45, 25), "covering UR corner");
2581  non_reducing(Rect::MakeLTRB(35, 35, 45, 45), "covering LR corner");
2582  non_reducing(Rect::MakeLTRB(15, 35, 25, 45), "covering LL corner");
2583 
2584  // Overlap edges, but not across an entire side
2585  non_reducing(Rect::MakeLTRB(20, 15, 39, 25), "Top edge left-biased");
2586  non_reducing(Rect::MakeLTRB(21, 15, 40, 25), "Top edge, right biased");
2587  non_reducing(Rect::MakeLTRB(35, 20, 45, 39), "Right edge, top-biased");
2588  non_reducing(Rect::MakeLTRB(35, 21, 45, 40), "Right edge, bottom-biased");
2589  non_reducing(Rect::MakeLTRB(20, 35, 39, 45), "Bottom edge, left-biased");
2590  non_reducing(Rect::MakeLTRB(21, 35, 40, 45), "Bottom edge, right-biased");
2591  non_reducing(Rect::MakeLTRB(15, 20, 25, 39), "Left edge, top-biased");
2592  non_reducing(Rect::MakeLTRB(15, 21, 25, 40), "Left edge, bottom-biased");
2593 
2594  // Slice all the way through the middle
2595  non_reducing(Rect::MakeLTRB(25, 15, 35, 45), "Vertical interior slice");
2596  non_reducing(Rect::MakeLTRB(15, 25, 45, 35), "Horizontal interior slice");
2597 
2598  // Slice off each edge
2599  reducing(Rect::MakeLTRB(20, 15, 40, 25), //
2600  Rect::MakeLTRB(20, 25, 40, 40), //
2601  "Slice off top");
2602  reducing(Rect::MakeLTRB(35, 20, 45, 40), //
2603  Rect::MakeLTRB(20, 20, 35, 40), //
2604  "Slice off right");
2605  reducing(Rect::MakeLTRB(20, 35, 40, 45), //
2606  Rect::MakeLTRB(20, 20, 40, 35), //
2607  "Slice off bottom");
2608  reducing(Rect::MakeLTRB(15, 20, 25, 40), //
2609  Rect::MakeLTRB(25, 20, 40, 40), //
2610  "Slice off left");
2611 
2612  // cull rect contains diff rect
2613  non_reducing(Rect::MakeLTRB(21, 21, 39, 39), "Contained, non-covering");
2614 
2615  // cull rect equals diff rect
2616  emptying(cull_rect, "Perfectly covering");
2617 
2618  // diff rect contains cull rect
2619  emptying(Rect::MakeLTRB(15, 15, 45, 45), "Smothering");
2620 }

References impeller::TRect< T >::Cutout(), impeller::TRect< T >::CutoutOrEmpty(), flip_lr(), flip_lrtb(), flip_tb(), impeller::TRect< T >::IsEmpty(), impeller::TRect< T >::IsFinite(), impeller::TRect< Scalar >::MakeLTRB(), and swap_nan().

◆ TEST() [282/370]

impeller::testing::TEST ( RectTest  ,
RectDefaultConstructor   
)

Definition at line 44 of file rect_unittests.cc.

44  {
45  Rect rect = Rect();
46 
47  EXPECT_EQ(rect.GetLeft(), 0.0f);
48  EXPECT_EQ(rect.GetTop(), 0.0f);
49  EXPECT_EQ(rect.GetRight(), 0.0f);
50  EXPECT_EQ(rect.GetBottom(), 0.0f);
51  EXPECT_EQ(rect.GetX(), 0.0f);
52  EXPECT_EQ(rect.GetY(), 0.0f);
53  EXPECT_EQ(rect.GetWidth(), 0.0f);
54  EXPECT_EQ(rect.GetHeight(), 0.0f);
55  EXPECT_TRUE(rect.IsEmpty());
56  EXPECT_TRUE(rect.IsFinite());
57 }

References impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetTop(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetY(), impeller::TRect< T >::IsEmpty(), and impeller::TRect< T >::IsFinite().

◆ TEST() [283/370]

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

Definition at line 2812 of file rect_unittests.cc.

2812  {
2813  auto r = Rect::MakeLTRB(1, 2, 3, 4);
2814 
2815  EXPECT_EQ(r.GetLeft(), 1);
2816  EXPECT_EQ(r.GetTop(), 2);
2817  EXPECT_EQ(r.GetRight(), 3);
2818  EXPECT_EQ(r.GetBottom(), 4);
2819 
2820  EXPECT_POINT_NEAR(r.GetLeftTop(), Point(1, 2));
2821  EXPECT_POINT_NEAR(r.GetRightTop(), Point(3, 2));
2822  EXPECT_POINT_NEAR(r.GetLeftBottom(), Point(1, 4));
2823  EXPECT_POINT_NEAR(r.GetRightBottom(), Point(3, 4));
2824 }

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

◆ TEST() [284/370]

impeller::testing::TEST ( RectTest  ,
RectDoesNotIntersectEmpty   
)

Definition at line 764 of file rect_unittests.cc.

764  {
765  Rect rect = Rect::MakeLTRB(50, 50, 100, 100);
766 
767  auto test = [&rect](Scalar l, Scalar t, Scalar r, Scalar b,
768  const std::string& label) {
769  EXPECT_FALSE(rect.IntersectsWithRect(Rect::MakeLTRB(l, b, r, t)))
770  << label << " with Top/Bottom swapped";
771  EXPECT_FALSE(rect.IntersectsWithRect(Rect::MakeLTRB(r, b, l, t)))
772  << label << " with Left/Right swapped";
773  EXPECT_FALSE(rect.IntersectsWithRect(Rect::MakeLTRB(r, t, l, b)))
774  << label << " with all sides swapped";
775  };
776 
777  test(20, 20, 30, 30, "Above and Left");
778  test(70, 20, 80, 30, "Above");
779  test(120, 20, 130, 30, "Above and Right");
780  test(120, 70, 130, 80, "Right");
781  test(120, 120, 130, 130, "Below and Right");
782  test(70, 120, 80, 130, "Below");
783  test(20, 120, 30, 130, "Below and Left");
784  test(20, 70, 30, 80, "Left");
785 
786  test(70, 70, 80, 80, "Inside");
787 
788  test(40, 70, 60, 80, "Straddling Left");
789  test(70, 40, 80, 60, "Straddling Top");
790  test(90, 70, 110, 80, "Straddling Right");
791  test(70, 90, 80, 110, "Straddling Bottom");
792 }

References impeller::saturated::b, impeller::TRect< T >::IntersectsWithRect(), and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST() [285/370]

impeller::testing::TEST ( RectTest  ,
RectEmptyDeclaration   
)

Definition at line 14 of file rect_unittests.cc.

14  {
15  Rect rect;
16 
17  EXPECT_EQ(rect.GetLeft(), 0.0f);
18  EXPECT_EQ(rect.GetTop(), 0.0f);
19  EXPECT_EQ(rect.GetRight(), 0.0f);
20  EXPECT_EQ(rect.GetBottom(), 0.0f);
21  EXPECT_EQ(rect.GetX(), 0.0f);
22  EXPECT_EQ(rect.GetY(), 0.0f);
23  EXPECT_EQ(rect.GetWidth(), 0.0f);
24  EXPECT_EQ(rect.GetHeight(), 0.0f);
25  EXPECT_TRUE(rect.IsEmpty());
26  EXPECT_TRUE(rect.IsFinite());
27 }

References impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetTop(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetY(), impeller::TRect< T >::IsEmpty(), and impeller::TRect< T >::IsFinite().

◆ TEST() [286/370]

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

Definition at line 1205 of file rect_unittests.cc.

1205  {
1206  auto rect = Rect::MakeLTRB(100, 100, 200, 200);
1207 
1208  // Expand(T amount)
1209  EXPECT_EQ(rect.Expand(10), Rect::MakeLTRB(90, 90, 210, 210));
1210  EXPECT_EQ(rect.Expand(-10), Rect::MakeLTRB(110, 110, 190, 190));
1211 
1212  // Expand(amount, amount)
1213  EXPECT_EQ(rect.Expand(10, 10), Rect::MakeLTRB(90, 90, 210, 210));
1214  EXPECT_EQ(rect.Expand(10, -10), Rect::MakeLTRB(90, 110, 210, 190));
1215  EXPECT_EQ(rect.Expand(-10, 10), Rect::MakeLTRB(110, 90, 190, 210));
1216  EXPECT_EQ(rect.Expand(-10, -10), Rect::MakeLTRB(110, 110, 190, 190));
1217 
1218  // Expand(amount, amount, amount, amount)
1219  EXPECT_EQ(rect.Expand(10, 20, 30, 40), Rect::MakeLTRB(90, 80, 230, 240));
1220  EXPECT_EQ(rect.Expand(-10, 20, 30, 40), Rect::MakeLTRB(110, 80, 230, 240));
1221  EXPECT_EQ(rect.Expand(10, -20, 30, 40), Rect::MakeLTRB(90, 120, 230, 240));
1222  EXPECT_EQ(rect.Expand(10, 20, -30, 40), Rect::MakeLTRB(90, 80, 170, 240));
1223  EXPECT_EQ(rect.Expand(10, 20, 30, -40), Rect::MakeLTRB(90, 80, 230, 160));
1224 
1225  // Expand(Point amount)
1226  EXPECT_EQ(rect.Expand(Point{10, 10}), Rect::MakeLTRB(90, 90, 210, 210));
1227  EXPECT_EQ(rect.Expand(Point{10, -10}), Rect::MakeLTRB(90, 110, 210, 190));
1228  EXPECT_EQ(rect.Expand(Point{-10, 10}), Rect::MakeLTRB(110, 90, 190, 210));
1229  EXPECT_EQ(rect.Expand(Point{-10, -10}), Rect::MakeLTRB(110, 110, 190, 190));
1230 
1231  // Expand(Size amount)
1232  EXPECT_EQ(rect.Expand(Size{10, 10}), Rect::MakeLTRB(90, 90, 210, 210));
1233  EXPECT_EQ(rect.Expand(Size{10, -10}), Rect::MakeLTRB(90, 110, 210, 190));
1234  EXPECT_EQ(rect.Expand(Size{-10, 10}), Rect::MakeLTRB(110, 90, 190, 210));
1235  EXPECT_EQ(rect.Expand(Size{-10, -10}), Rect::MakeLTRB(110, 110, 190, 190));
1236 }

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

◆ TEST() [287/370]

impeller::testing::TEST ( RectTest  ,
RectFromRect   
)

Definition at line 609 of file rect_unittests.cc.

609  {
610  EXPECT_EQ(Rect(Rect::MakeXYWH(2, 3, 7, 15)),
611  Rect::MakeXYWH(2.0, 3.0, 7.0, 15.0));
612  EXPECT_EQ(Rect(Rect::MakeLTRB(2, 3, 7, 15)),
613  Rect::MakeLTRB(2.0, 3.0, 7.0, 15.0));
614 }

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

◆ TEST() [288/370]

impeller::testing::TEST ( RectTest  ,
RectGetNormalizingTransform   
)

Definition at line 989 of file rect_unittests.cc.

989  {
990  {
991  // Checks for expected matrix values
992 
993  auto r = Rect::MakeXYWH(100, 200, 200, 400);
994 
995  EXPECT_EQ(r.GetNormalizingTransform(),
996  Matrix::MakeScale({0.005, 0.0025, 1.0}) *
997  Matrix::MakeTranslation({-100, -200}));
998  }
999 
1000  {
1001  // Checks for expected transform of points relative to the rect
1002 
1003  auto r = Rect::MakeLTRB(300, 500, 400, 700);
1004  auto m = r.GetNormalizingTransform();
1005 
1006  // The 4 corners of the rect => (0, 0) to (1, 1)
1007  EXPECT_EQ(m * Point(300, 500), Point(0, 0));
1008  EXPECT_EQ(m * Point(400, 500), Point(1, 0));
1009  EXPECT_EQ(m * Point(400, 700), Point(1, 1));
1010  EXPECT_EQ(m * Point(300, 700), Point(0, 1));
1011 
1012  // The center => (0.5, 0.5)
1013  EXPECT_EQ(m * Point(350, 600), Point(0.5, 0.5));
1014 
1015  // Outside the 4 corners => (-1, -1) to (2, 2)
1016  EXPECT_EQ(m * Point(200, 300), Point(-1, -1));
1017  EXPECT_EQ(m * Point(500, 300), Point(2, -1));
1018  EXPECT_EQ(m * Point(500, 900), Point(2, 2));
1019  EXPECT_EQ(m * Point(200, 900), Point(-1, 2));
1020  }
1021 
1022  {
1023  // Checks for behavior with empty rects
1024 
1025  auto zero = Matrix::MakeScale({0.0, 0.0, 1.0});
1026 
1027  // Empty for width and/or height == 0
1028  EXPECT_EQ(Rect::MakeXYWH(10, 10, 0, 10).GetNormalizingTransform(), zero);
1029  EXPECT_EQ(Rect::MakeXYWH(10, 10, 10, 0).GetNormalizingTransform(), zero);
1030  EXPECT_EQ(Rect::MakeXYWH(10, 10, 0, 0).GetNormalizingTransform(), zero);
1031 
1032  // Empty for width and/or height < 0
1033  EXPECT_EQ(Rect::MakeXYWH(10, 10, -1, 10).GetNormalizingTransform(), zero);
1034  EXPECT_EQ(Rect::MakeXYWH(10, 10, 10, -1).GetNormalizingTransform(), zero);
1035  EXPECT_EQ(Rect::MakeXYWH(10, 10, -1, -1).GetNormalizingTransform(), zero);
1036  }
1037 
1038  {
1039  // Checks for behavior with non-finite rects
1040 
1041  auto z = Matrix::MakeScale({0.0, 0.0, 1.0});
1042  auto nan = std::numeric_limits<Scalar>::quiet_NaN();
1043  auto inf = std::numeric_limits<Scalar>::infinity();
1044 
1045  // Non-finite for width and/or height == nan
1046  EXPECT_EQ(Rect::MakeXYWH(10, 10, nan, 10).GetNormalizingTransform(), z);
1047  EXPECT_EQ(Rect::MakeXYWH(10, 10, 10, nan).GetNormalizingTransform(), z);
1048  EXPECT_EQ(Rect::MakeXYWH(10, 10, nan, nan).GetNormalizingTransform(), z);
1049 
1050  // Non-finite for width and/or height == inf
1051  EXPECT_EQ(Rect::MakeXYWH(10, 10, inf, 10).GetNormalizingTransform(), z);
1052  EXPECT_EQ(Rect::MakeXYWH(10, 10, 10, inf).GetNormalizingTransform(), z);
1053  EXPECT_EQ(Rect::MakeXYWH(10, 10, inf, inf).GetNormalizingTransform(), z);
1054 
1055  // Non-finite for width and/or height == -inf
1056  EXPECT_EQ(Rect::MakeXYWH(10, 10, -inf, 10).GetNormalizingTransform(), z);
1057  EXPECT_EQ(Rect::MakeXYWH(10, 10, 10, -inf).GetNormalizingTransform(), z);
1058  EXPECT_EQ(Rect::MakeXYWH(10, 10, -inf, -inf).GetNormalizingTransform(), z);
1059 
1060  // Non-finite for origin X and/or Y == nan
1061  EXPECT_EQ(Rect::MakeXYWH(nan, 10, 10, 10).GetNormalizingTransform(), z);
1062  EXPECT_EQ(Rect::MakeXYWH(10, nan, 10, 10).GetNormalizingTransform(), z);
1063  EXPECT_EQ(Rect::MakeXYWH(nan, nan, 10, 10).GetNormalizingTransform(), z);
1064 
1065  // Non-finite for origin X and/or Y == inf
1066  EXPECT_EQ(Rect::MakeXYWH(inf, 10, 10, 10).GetNormalizingTransform(), z);
1067  EXPECT_EQ(Rect::MakeXYWH(10, inf, 10, 10).GetNormalizingTransform(), z);
1068  EXPECT_EQ(Rect::MakeXYWH(inf, inf, 10, 10).GetNormalizingTransform(), z);
1069 
1070  // Non-finite for origin X and/or Y == -inf
1071  EXPECT_EQ(Rect::MakeXYWH(-inf, 10, 10, 10).GetNormalizingTransform(), z);
1072  EXPECT_EQ(Rect::MakeXYWH(10, -inf, 10, 10).GetNormalizingTransform(), z);
1073  EXPECT_EQ(Rect::MakeXYWH(-inf, -inf, 10, 10).GetNormalizingTransform(), z);
1074  }
1075 }

References impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [289/370]

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

Definition at line 2741 of file rect_unittests.cc.

2741  {
2742  {
2743  Rect r = Rect::MakeXYWH(100, 200, 300, 400);
2744  auto points = r.GetPoints();
2745  EXPECT_POINT_NEAR(points[0], Point(100, 200));
2746  EXPECT_POINT_NEAR(points[1], Point(400, 200));
2747  EXPECT_POINT_NEAR(points[2], Point(100, 600));
2748  EXPECT_POINT_NEAR(points[3], Point(400, 600));
2749  }
2750 
2751  {
2752  Rect r = Rect::MakeMaximum();
2753  auto points = r.GetPoints();
2754  EXPECT_EQ(points[0], Point(std::numeric_limits<float>::lowest(),
2755  std::numeric_limits<float>::lowest()));
2756  EXPECT_EQ(points[1], Point(std::numeric_limits<float>::max(),
2757  std::numeric_limits<float>::lowest()));
2758  EXPECT_EQ(points[2], Point(std::numeric_limits<float>::lowest(),
2759  std::numeric_limits<float>::max()));
2760  EXPECT_EQ(points[3], Point(std::numeric_limits<float>::max(),
2761  std::numeric_limits<float>::max()));
2762  }
2763 }

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

◆ TEST() [290/370]

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

Definition at line 2798 of file rect_unittests.cc.

2798  {
2799  {
2800  Rect r = Rect::MakeXYWH(100, 200, 300, 400);
2801  auto actual = r.GetPositive();
2802  EXPECT_RECT_NEAR(r, actual);
2803  }
2804  {
2805  Rect r = Rect::MakeXYWH(100, 200, -100, -100);
2806  auto actual = r.GetPositive();
2807  Rect expected = Rect::MakeXYWH(0, 100, 100, 100);
2808  EXPECT_RECT_NEAR(expected, actual);
2809  }
2810 }

References EXPECT_RECT_NEAR, impeller::TRect< T >::GetPositive(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [291/370]

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

Definition at line 2772 of file rect_unittests.cc.

2772  {
2773  Rect r = Rect::MakeXYWH(100, 200, 300, 400);
2774  auto points = r.GetTransformedPoints(Matrix::MakeTranslation({10, 20}));
2775  EXPECT_POINT_NEAR(points[0], Point(110, 220));
2776  EXPECT_POINT_NEAR(points[1], Point(410, 220));
2777  EXPECT_POINT_NEAR(points[2], Point(110, 620));
2778  EXPECT_POINT_NEAR(points[3], Point(410, 620));
2779 }

References EXPECT_POINT_NEAR, impeller::TRect< T >::GetTransformedPoints(), impeller::Matrix::MakeTranslation(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [292/370]

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

Definition at line 1580 of file rect_unittests.cc.

1580  {
1581  auto check_nans = [](const Rect& a, const Rect& b, const std::string& label) {
1582  ASSERT_TRUE(a.IsFinite()) << label;
1583  ASSERT_TRUE(b.IsFinite()) << label;
1584 
1585  for (int i = 1; i < 16; i++) {
1586  // NaN in a produces empty
1587  EXPECT_FALSE(swap_nan(a, i).Intersection(b).has_value())
1588  << label << ", index = " << i;
1589  // NaN in b produces empty
1590  EXPECT_FALSE(a.Intersection(swap_nan(b, i)).has_value())
1591  << label << ", index = " << i;
1592  // NaN in both is empty
1593  for (int j = 1; j < 16; j++) {
1594  EXPECT_FALSE(swap_nan(a, i).Intersection(swap_nan(b, j)).has_value())
1595  << label << ", indices = " << i << ", " << j;
1596  }
1597  }
1598  };
1599 
1600  auto check_empty_flips = [](const Rect& a, const Rect& b,
1601  const std::string& label) {
1602  ASSERT_FALSE(a.IsEmpty());
1603  // b is allowed to be empty
1604 
1605  // unflipped a vs flipped (empty) b yields a
1606  EXPECT_FALSE(a.Intersection(flip_lr(b)).has_value()) << label;
1607  EXPECT_FALSE(a.Intersection(flip_tb(b)).has_value()) << label;
1608  EXPECT_FALSE(a.Intersection(flip_lrtb(b)).has_value()) << label;
1609 
1610  // flipped (empty) a vs unflipped b yields b
1611  EXPECT_FALSE(flip_lr(a).Intersection(b).has_value()) << label;
1612  EXPECT_FALSE(flip_tb(a).Intersection(b).has_value()) << label;
1613  EXPECT_FALSE(flip_lrtb(a).Intersection(b).has_value()) << label;
1614 
1615  // flipped (empty) a vs flipped (empty) b yields empty
1616  EXPECT_FALSE(flip_lr(a).Intersection(flip_lr(b)).has_value()) << label;
1617  EXPECT_FALSE(flip_tb(a).Intersection(flip_tb(b)).has_value()) << label;
1618  EXPECT_FALSE(flip_lrtb(a).Intersection(flip_lrtb(b)).has_value()) << label;
1619  };
1620 
1621  auto test_non_empty = [&check_nans, &check_empty_flips](
1622  const Rect& a, const Rect& b, const Rect& result) {
1623  ASSERT_FALSE(a.IsEmpty()) << a;
1624  // b is allowed to be empty
1625 
1626  std::stringstream stream;
1627  stream << a << " union " << b;
1628  auto label = stream.str();
1629 
1630  EXPECT_TRUE(a.Intersection(b).has_value()) << label;
1631  EXPECT_TRUE(b.Intersection(a).has_value()) << label;
1632  EXPECT_EQ(a.Intersection(b), result) << label;
1633  EXPECT_EQ(b.Intersection(a), result) << label;
1634  check_empty_flips(a, b, label);
1635  check_nans(a, b, label);
1636  };
1637 
1638  auto test_empty = [&check_nans, &check_empty_flips](const Rect& a,
1639  const Rect& b) {
1640  ASSERT_FALSE(a.IsEmpty()) << a;
1641  // b is allowed to be empty
1642 
1643  std::stringstream stream;
1644  stream << a << " union " << b;
1645  auto label = stream.str();
1646 
1647  EXPECT_FALSE(a.Intersection(b).has_value()) << label;
1648  EXPECT_FALSE(b.Intersection(a).has_value()) << label;
1649  check_empty_flips(a, b, label);
1650  check_nans(a, b, label);
1651  };
1652 
1653  {
1654  auto a = Rect::MakeXYWH(100, 100, 100, 100);
1655  auto b = Rect::MakeXYWH(0, 0, 0, 0);
1656 
1657  test_empty(a, b);
1658  }
1659 
1660  {
1661  auto a = Rect::MakeXYWH(100, 100, 100, 100);
1662  auto b = Rect::MakeXYWH(10, 10, 0, 0);
1663 
1664  test_empty(a, b);
1665  }
1666 
1667  {
1668  auto a = Rect::MakeXYWH(0, 0, 100, 100);
1669  auto b = Rect::MakeXYWH(10, 10, 100, 100);
1670  auto expected = Rect::MakeXYWH(10, 10, 90, 90);
1671 
1672  test_non_empty(a, b, expected);
1673  }
1674 
1675  {
1676  auto a = Rect::MakeXYWH(0, 0, 100, 100);
1677  auto b = Rect::MakeXYWH(100, 100, 100, 100);
1678 
1679  test_empty(a, b);
1680  }
1681 
1682  {
1683  auto a = Rect::MakeMaximum();
1684  auto b = Rect::MakeXYWH(10, 10, 300, 300);
1685 
1686  test_non_empty(a, b, b);
1687  }
1688 
1689  {
1690  auto a = Rect::MakeMaximum();
1691  auto b = Rect::MakeMaximum();
1692 
1693  test_non_empty(a, b, Rect::MakeMaximum());
1694  }
1695 }

References impeller::saturated::b, flip_lr(), flip_lrtb(), flip_tb(), impeller::TRect< T >::Intersection(), impeller::TRect< T >::IsEmpty(), impeller::TRect< T >::IsFinite(), impeller::TRect< Scalar >::MakeMaximum(), impeller::TRect< Scalar >::MakeXYWH(), and swap_nan().

◆ TEST() [293/370]

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

Definition at line 1902 of file rect_unittests.cc.

1902  {
1903  auto check_nans = [](const Rect& a, const Rect& b, const std::string& label) {
1904  ASSERT_TRUE(a.IsFinite()) << label;
1905  ASSERT_TRUE(b.IsFinite()) << label;
1906 
1907  for (int i = 1; i < 16; i++) {
1908  // NaN in a produces b
1909  EXPECT_FALSE(swap_nan(a, i).IntersectsWithRect(b))
1910  << label << ", index = " << i;
1911  // NaN in b produces a
1912  EXPECT_FALSE(a.IntersectsWithRect(swap_nan(b, i)))
1913  << label << ", index = " << i;
1914  // NaN in both is empty
1915  for (int j = 1; j < 16; j++) {
1916  EXPECT_FALSE(swap_nan(a, i).IntersectsWithRect(swap_nan(b, j)))
1917  << label << ", indices = " << i << ", " << j;
1918  }
1919  }
1920  };
1921 
1922  auto check_empty_flips = [](const Rect& a, const Rect& b,
1923  const std::string& label) {
1924  ASSERT_FALSE(a.IsEmpty());
1925  // b is allowed to be empty
1926 
1927  // unflipped a vs flipped (empty) b yields a
1928  EXPECT_FALSE(a.IntersectsWithRect(flip_lr(b))) << label;
1929  EXPECT_FALSE(a.IntersectsWithRect(flip_tb(b))) << label;
1930  EXPECT_FALSE(a.IntersectsWithRect(flip_lrtb(b))) << label;
1931 
1932  // flipped (empty) a vs unflipped b yields b
1933  EXPECT_FALSE(flip_lr(a).IntersectsWithRect(b)) << label;
1934  EXPECT_FALSE(flip_tb(a).IntersectsWithRect(b)) << label;
1935  EXPECT_FALSE(flip_lrtb(a).IntersectsWithRect(b)) << label;
1936 
1937  // flipped (empty) a vs flipped (empty) b yields empty
1938  EXPECT_FALSE(flip_lr(a).IntersectsWithRect(flip_lr(b))) << label;
1939  EXPECT_FALSE(flip_tb(a).IntersectsWithRect(flip_tb(b))) << label;
1940  EXPECT_FALSE(flip_lrtb(a).IntersectsWithRect(flip_lrtb(b))) << label;
1941  };
1942 
1943  auto test_non_empty = [&check_nans, &check_empty_flips](const Rect& a,
1944  const Rect& b) {
1945  ASSERT_FALSE(a.IsEmpty()) << a;
1946  // b is allowed to be empty
1947 
1948  std::stringstream stream;
1949  stream << a << " union " << b;
1950  auto label = stream.str();
1951 
1952  EXPECT_TRUE(a.IntersectsWithRect(b)) << label;
1953  EXPECT_TRUE(b.IntersectsWithRect(a)) << label;
1954  check_empty_flips(a, b, label);
1955  check_nans(a, b, label);
1956  };
1957 
1958  auto test_empty = [&check_nans, &check_empty_flips](const Rect& a,
1959  const Rect& b) {
1960  ASSERT_FALSE(a.IsEmpty()) << a;
1961  // b is allowed to be empty
1962 
1963  std::stringstream stream;
1964  stream << a << " union " << b;
1965  auto label = stream.str();
1966 
1967  EXPECT_FALSE(a.IntersectsWithRect(b)) << label;
1968  EXPECT_FALSE(b.IntersectsWithRect(a)) << label;
1969  check_empty_flips(a, b, label);
1970  check_nans(a, b, label);
1971  };
1972 
1973  {
1974  auto a = Rect::MakeXYWH(100, 100, 100, 100);
1975  auto b = Rect::MakeXYWH(0, 0, 0, 0);
1976 
1977  test_empty(a, b);
1978  }
1979 
1980  {
1981  auto a = Rect::MakeXYWH(100, 100, 100, 100);
1982  auto b = Rect::MakeXYWH(10, 10, 0, 0);
1983 
1984  test_empty(a, b);
1985  }
1986 
1987  {
1988  auto a = Rect::MakeXYWH(0, 0, 100, 100);
1989  auto b = Rect::MakeXYWH(10, 10, 100, 100);
1990 
1991  test_non_empty(a, b);
1992  }
1993 
1994  {
1995  auto a = Rect::MakeXYWH(0, 0, 100, 100);
1996  auto b = Rect::MakeXYWH(100, 100, 100, 100);
1997 
1998  test_empty(a, b);
1999  }
2000 
2001  {
2002  auto a = Rect::MakeMaximum();
2003  auto b = Rect::MakeXYWH(10, 10, 100, 100);
2004 
2005  test_non_empty(a, b);
2006  }
2007 
2008  {
2009  auto a = Rect::MakeMaximum();
2010  auto b = Rect::MakeMaximum();
2011 
2012  test_non_empty(a, b);
2013  }
2014 }

References impeller::saturated::b, flip_lr(), flip_lrtb(), flip_tb(), impeller::TRect< T >::IntersectsWithRect(), impeller::TRect< T >::IsEmpty(), impeller::TRect< T >::IsFinite(), impeller::TRect< Scalar >::MakeMaximum(), impeller::TRect< Scalar >::MakeXYWH(), and swap_nan().

◆ TEST() [294/370]

impeller::testing::TEST ( RectTest  ,
RectMakeMaximum   
)

Definition at line 575 of file rect_unittests.cc.

575  {
576  Rect rect = Rect::MakeMaximum();
577  auto inf = std::numeric_limits<Scalar>::infinity();
578  auto min = std::numeric_limits<Scalar>::lowest();
579  auto max = std::numeric_limits<Scalar>::max();
580 
581  EXPECT_EQ(rect.GetLeft(), min);
582  EXPECT_EQ(rect.GetTop(), min);
583  EXPECT_EQ(rect.GetRight(), max);
584  EXPECT_EQ(rect.GetBottom(), max);
585  EXPECT_EQ(rect.GetX(), min);
586  EXPECT_EQ(rect.GetY(), min);
587  EXPECT_EQ(rect.GetWidth(), inf);
588  EXPECT_EQ(rect.GetHeight(), inf);
589  EXPECT_FALSE(rect.IsEmpty());
590  EXPECT_TRUE(rect.IsFinite());
591 }

References impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetTop(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetY(), impeller::TRect< T >::IsEmpty(), impeller::TRect< T >::IsFinite(), and impeller::TRect< Scalar >::MakeMaximum().

◆ TEST() [295/370]

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

Definition at line 2781 of file rect_unittests.cc.

2781  {
2782  {
2783  std::vector<Point> points{{1, 5}, {4, -1}, {0, 6}};
2784  auto r = Rect::MakePointBounds(points.begin(), points.end());
2785  auto expected = Rect::MakeXYWH(0, -1, 4, 7);
2786  EXPECT_TRUE(r.has_value());
2787  if (r.has_value()) {
2788  EXPECT_RECT_NEAR(r.value(), expected);
2789  }
2790  }
2791  {
2792  std::vector<Point> points;
2793  std::optional<Rect> r = Rect::MakePointBounds(points.begin(), points.end());
2794  EXPECT_FALSE(r.has_value());
2795  }
2796 }

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

◆ TEST() [296/370]

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

Definition at line 545 of file rect_unittests.cc.

545  {
546  {
547  Size s(100, 200);
548  Rect r = Rect::MakeSize(s);
549  Rect expected = Rect::MakeLTRB(0, 0, 100, 200);
550  EXPECT_RECT_NEAR(r, expected);
551  }
552 
553  {
554  ISize s(100, 200);
555  Rect r = Rect::MakeSize(s);
556  Rect expected = Rect::MakeLTRB(0, 0, 100, 200);
557  EXPECT_RECT_NEAR(r, expected);
558  }
559 
560  {
561  Size s(100, 200);
562  IRect r = IRect::MakeSize(s);
563  IRect expected = IRect::MakeLTRB(0, 0, 100, 200);
564  EXPECT_EQ(r, expected);
565  }
566 
567  {
568  ISize s(100, 200);
569  IRect r = IRect::MakeSize(s);
570  IRect expected = IRect::MakeLTRB(0, 0, 100, 200);
571  EXPECT_EQ(r, expected);
572  }
573 }

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

◆ TEST() [297/370]

impeller::testing::TEST ( RectTest  ,
RectOriginSizeXYWHGetters   
)

Definition at line 657 of file rect_unittests.cc.

657  {
658  {
659  Rect r = Rect::MakeOriginSize({10, 20}, {50, 40});
660  EXPECT_EQ(r.GetOrigin(), Point(10, 20));
661  EXPECT_EQ(r.GetSize(), Size(50, 40));
662  EXPECT_EQ(r.GetX(), 10);
663  EXPECT_EQ(r.GetY(), 20);
664  EXPECT_EQ(r.GetWidth(), 50);
665  EXPECT_EQ(r.GetHeight(), 40);
666  auto expected_array = std::array<Scalar, 4>{10, 20, 50, 40};
667  EXPECT_EQ(r.GetXYWH(), expected_array);
668  }
669 
670  {
671  Rect r = Rect::MakeLTRB(10, 20, 50, 40);
672  EXPECT_EQ(r.GetOrigin(), Point(10, 20));
673  EXPECT_EQ(r.GetSize(), Size(40, 20));
674  EXPECT_EQ(r.GetX(), 10);
675  EXPECT_EQ(r.GetY(), 20);
676  EXPECT_EQ(r.GetWidth(), 40);
677  EXPECT_EQ(r.GetHeight(), 20);
678  auto expected_array = std::array<Scalar, 4>{10, 20, 40, 20};
679  EXPECT_EQ(r.GetXYWH(), expected_array);
680  }
681 }

References impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetOrigin(), impeller::TRect< T >::GetSize(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetXYWH(), impeller::TRect< T >::GetY(), impeller::TRect< Scalar >::MakeLTRB(), and impeller::TRect< Scalar >::MakeOriginSize().

◆ TEST() [298/370]

impeller::testing::TEST ( RectTest  ,
RectOverflowLTRB   
)

Definition at line 339 of file rect_unittests.cc.

339  {
340  auto min = std::numeric_limits<Scalar>::lowest();
341  auto max = std::numeric_limits<Scalar>::max();
342  auto inf = std::numeric_limits<Scalar>::infinity();
343 
344  // 8 cases:
345  // finite negative X, max W
346  // ~min X, ~max W
347  // finite negative Y, max H
348  // ~min Y, ~max H
349  // finite positive X, min W
350  // ~min X, ~min W
351  // finite positive Y, min H
352  // ~min Y, ~min H
353 
354  // a small finite value subtracted from a max value will remain max
355  // a very large finite value (like min) subtracted from max will go to inf
356 
357  {
358  Rect rect = Rect::MakeLTRB(-5.0f, 10.0f, max, 25.0f);
359 
360  EXPECT_EQ(rect.GetLeft(), -5.0f);
361  EXPECT_EQ(rect.GetTop(), 10.0f);
362  EXPECT_EQ(rect.GetRight(), max);
363  EXPECT_EQ(rect.GetBottom(), 25.0f);
364  EXPECT_EQ(rect.GetX(), -5.0f);
365  EXPECT_EQ(rect.GetY(), 10.0f);
366  EXPECT_EQ(rect.GetWidth(), max);
367  EXPECT_EQ(rect.GetHeight(), 15.0f);
368  EXPECT_FALSE(rect.IsEmpty());
369  EXPECT_TRUE(rect.IsFinite());
370  }
371 
372  {
373  Rect rect = Rect::MakeLTRB(min + 5.0f, 10.0f, max - 5.0f, 25.0f);
374 
375  EXPECT_EQ(rect.GetLeft(), min + 5.0f);
376  EXPECT_EQ(rect.GetTop(), 10.0f);
377  EXPECT_EQ(rect.GetRight(), max - 5.0f);
378  EXPECT_EQ(rect.GetBottom(), 25.0f);
379  EXPECT_EQ(rect.GetX(), min + 5.0f);
380  EXPECT_EQ(rect.GetY(), 10.0f);
381  EXPECT_EQ(rect.GetWidth(), inf);
382  EXPECT_EQ(rect.GetHeight(), 15.0f);
383  EXPECT_FALSE(rect.IsEmpty());
384  EXPECT_TRUE(rect.IsFinite());
385  }
386 
387  {
388  Rect rect = Rect::MakeLTRB(5.0f, -10.0f, 20.0f, max);
389 
390  EXPECT_EQ(rect.GetLeft(), 5.0f);
391  EXPECT_EQ(rect.GetTop(), -10.0f);
392  EXPECT_EQ(rect.GetRight(), 20.0f);
393  EXPECT_EQ(rect.GetBottom(), max);
394  EXPECT_EQ(rect.GetX(), 5.0f);
395  EXPECT_EQ(rect.GetY(), -10.0f);
396  EXPECT_EQ(rect.GetWidth(), 15.0f);
397  EXPECT_EQ(rect.GetHeight(), max);
398  EXPECT_FALSE(rect.IsEmpty());
399  EXPECT_TRUE(rect.IsFinite());
400  }
401 
402  {
403  Rect rect = Rect::MakeLTRB(5.0f, min + 10.0f, 20.0f, max - 15.0f);
404 
405  EXPECT_EQ(rect.GetLeft(), 5.0f);
406  EXPECT_EQ(rect.GetTop(), min + 10.0f);
407  EXPECT_EQ(rect.GetRight(), 20.0f);
408  EXPECT_EQ(rect.GetBottom(), max - 15.0f);
409  EXPECT_EQ(rect.GetX(), 5.0f);
410  EXPECT_EQ(rect.GetY(), min + 10.0f);
411  EXPECT_EQ(rect.GetWidth(), 15.0f);
412  EXPECT_EQ(rect.GetHeight(), inf);
413  EXPECT_FALSE(rect.IsEmpty());
414  EXPECT_TRUE(rect.IsFinite());
415  }
416 
417  {
418  Rect rect = Rect::MakeLTRB(5.0f, 10.0f, min, 25.0f);
419 
420  EXPECT_EQ(rect.GetLeft(), 5.0f);
421  EXPECT_EQ(rect.GetTop(), 10.0f);
422  EXPECT_EQ(rect.GetRight(), min);
423  EXPECT_EQ(rect.GetBottom(), 25.0f);
424  EXPECT_EQ(rect.GetX(), 5.0f);
425  EXPECT_EQ(rect.GetY(), 10.0f);
426  EXPECT_EQ(rect.GetWidth(), min);
427  EXPECT_EQ(rect.GetHeight(), 15.0f);
428  EXPECT_TRUE(rect.IsEmpty());
429  EXPECT_TRUE(rect.IsFinite());
430  }
431 
432  {
433  Rect rect = Rect::MakeLTRB(max - 5.0f, 10.0f, min + 10.0f, 25.0f);
434 
435  EXPECT_EQ(rect.GetLeft(), max - 5.0f);
436  EXPECT_EQ(rect.GetTop(), 10.0f);
437  EXPECT_EQ(rect.GetRight(), min + 10.0f);
438  EXPECT_EQ(rect.GetBottom(), 25.0f);
439  EXPECT_EQ(rect.GetX(), max - 5.0f);
440  EXPECT_EQ(rect.GetY(), 10.0f);
441  EXPECT_EQ(rect.GetWidth(), -inf);
442  EXPECT_EQ(rect.GetHeight(), 15.0f);
443  EXPECT_TRUE(rect.IsEmpty());
444  EXPECT_TRUE(rect.IsFinite());
445  }
446 
447  {
448  Rect rect = Rect::MakeLTRB(5.0f, 10.0f, 20.0f, min);
449 
450  EXPECT_EQ(rect.GetLeft(), 5.0f);
451  EXPECT_EQ(rect.GetTop(), 10.0f);
452  EXPECT_EQ(rect.GetRight(), 20.0f);
453  EXPECT_EQ(rect.GetBottom(), min);
454  EXPECT_EQ(rect.GetX(), 5.0f);
455  EXPECT_EQ(rect.GetY(), 10.0f);
456  EXPECT_EQ(rect.GetWidth(), 15.0f);
457  EXPECT_EQ(rect.GetHeight(), min);
458  EXPECT_TRUE(rect.IsEmpty());
459  EXPECT_TRUE(rect.IsFinite());
460  }
461 
462  {
463  Rect rect = Rect::MakeLTRB(5.0f, max - 5.0f, 20.0f, min + 10.0f);
464 
465  EXPECT_EQ(rect.GetLeft(), 5.0f);
466  EXPECT_EQ(rect.GetTop(), max - 5.0f);
467  EXPECT_EQ(rect.GetRight(), 20.0f);
468  EXPECT_EQ(rect.GetBottom(), min + 10.0f);
469  EXPECT_EQ(rect.GetX(), 5.0f);
470  EXPECT_EQ(rect.GetY(), max - 5.0f);
471  EXPECT_EQ(rect.GetWidth(), 15.0f);
472  EXPECT_EQ(rect.GetHeight(), -inf);
473  EXPECT_TRUE(rect.IsEmpty());
474  EXPECT_TRUE(rect.IsFinite());
475  }
476 }

References impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetTop(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetY(), impeller::TRect< T >::IsEmpty(), impeller::TRect< T >::IsFinite(), and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST() [299/370]

impeller::testing::TEST ( RectTest  ,
RectOverflowXYWH   
)

Definition at line 133 of file rect_unittests.cc.

133  {
134  auto min = std::numeric_limits<Scalar>::lowest();
135  auto max = std::numeric_limits<Scalar>::max();
136  auto inf = std::numeric_limits<Scalar>::infinity();
137 
138  // 8 cases:
139  // finite X, max W
140  // max X, max W
141  // finite Y, max H
142  // max Y, max H
143  // finite X, min W
144  // min X, min W
145  // finite Y, min H
146  // min Y, min H
147 
148  // a small finite value added to a max value will remain max
149  // a very large finite value (like max) added to max will go to infinity
150 
151  {
152  Rect rect = Rect::MakeXYWH(5.0, 10.0f, max, 15.0f);
153 
154  EXPECT_EQ(rect.GetLeft(), 5.0f);
155  EXPECT_EQ(rect.GetTop(), 10.0f);
156  EXPECT_EQ(rect.GetRight(), max);
157  EXPECT_EQ(rect.GetBottom(), 25.0f);
158  EXPECT_EQ(rect.GetX(), 5.0f);
159  EXPECT_EQ(rect.GetY(), 10.0f);
160  EXPECT_EQ(rect.GetWidth(), max);
161  EXPECT_EQ(rect.GetHeight(), 15.0f);
162  EXPECT_FALSE(rect.IsEmpty());
163  EXPECT_TRUE(rect.IsFinite());
164  }
165 
166  {
167  Rect rect = Rect::MakeXYWH(max, 10.0f, max, 15.0f);
168 
169  EXPECT_EQ(rect.GetLeft(), max);
170  EXPECT_EQ(rect.GetTop(), 10.0f);
171  EXPECT_EQ(rect.GetRight(), inf);
172  EXPECT_EQ(rect.GetBottom(), 25.0f);
173  EXPECT_EQ(rect.GetX(), max);
174  EXPECT_EQ(rect.GetY(), 10.0f);
175  EXPECT_EQ(rect.GetWidth(), inf);
176  EXPECT_EQ(rect.GetHeight(), 15.0f);
177  EXPECT_FALSE(rect.IsEmpty());
178  EXPECT_FALSE(rect.IsFinite());
179  }
180 
181  {
182  Rect rect = Rect::MakeXYWH(5.0f, 10.0f, 20.0f, max);
183 
184  EXPECT_EQ(rect.GetLeft(), 5.0f);
185  EXPECT_EQ(rect.GetTop(), 10.0f);
186  EXPECT_EQ(rect.GetRight(), 25.0f);
187  EXPECT_EQ(rect.GetBottom(), max);
188  EXPECT_EQ(rect.GetX(), 5.0f);
189  EXPECT_EQ(rect.GetY(), 10.0f);
190  EXPECT_EQ(rect.GetWidth(), 20.0f);
191  EXPECT_EQ(rect.GetHeight(), max);
192  EXPECT_FALSE(rect.IsEmpty());
193  EXPECT_TRUE(rect.IsFinite());
194  }
195 
196  {
197  Rect rect = Rect::MakeXYWH(5.0f, max, 20.0f, max);
198 
199  EXPECT_EQ(rect.GetLeft(), 5.0f);
200  EXPECT_EQ(rect.GetTop(), max);
201  EXPECT_EQ(rect.GetRight(), 25.0f);
202  EXPECT_EQ(rect.GetBottom(), inf);
203  EXPECT_EQ(rect.GetX(), 5.0f);
204  EXPECT_EQ(rect.GetY(), max);
205  EXPECT_EQ(rect.GetWidth(), 20.0f);
206  EXPECT_EQ(rect.GetHeight(), inf);
207  EXPECT_FALSE(rect.IsEmpty());
208  EXPECT_FALSE(rect.IsFinite());
209  }
210 
211  {
212  Rect rect = Rect::MakeXYWH(5.0, 10.0f, min, 15.0f);
213 
214  EXPECT_EQ(rect.GetLeft(), 5.0f);
215  EXPECT_EQ(rect.GetTop(), 10.0f);
216  EXPECT_EQ(rect.GetRight(), min);
217  EXPECT_EQ(rect.GetBottom(), 25.0f);
218  EXPECT_EQ(rect.GetX(), 5.0f);
219  EXPECT_EQ(rect.GetY(), 10.0f);
220  EXPECT_EQ(rect.GetWidth(), min);
221  EXPECT_EQ(rect.GetHeight(), 15.0f);
222  EXPECT_TRUE(rect.IsEmpty());
223  EXPECT_TRUE(rect.IsFinite());
224  }
225 
226  {
227  Rect rect = Rect::MakeXYWH(min, 10.0f, min, 15.0f);
228 
229  EXPECT_EQ(rect.GetLeft(), min);
230  EXPECT_EQ(rect.GetTop(), 10.0f);
231  EXPECT_EQ(rect.GetRight(), -inf);
232  EXPECT_EQ(rect.GetBottom(), 25.0f);
233  EXPECT_EQ(rect.GetX(), min);
234  EXPECT_EQ(rect.GetY(), 10.0f);
235  EXPECT_EQ(rect.GetWidth(), -inf);
236  EXPECT_EQ(rect.GetHeight(), 15.0f);
237  EXPECT_TRUE(rect.IsEmpty());
238  EXPECT_FALSE(rect.IsFinite());
239  }
240 
241  {
242  Rect rect = Rect::MakeXYWH(5.0f, 10.0f, 20.0f, min);
243 
244  EXPECT_EQ(rect.GetLeft(), 5.0f);
245  EXPECT_EQ(rect.GetTop(), 10.0f);
246  EXPECT_EQ(rect.GetRight(), 25.0f);
247  EXPECT_EQ(rect.GetBottom(), min);
248  EXPECT_EQ(rect.GetX(), 5.0f);
249  EXPECT_EQ(rect.GetY(), 10.0f);
250  EXPECT_EQ(rect.GetWidth(), 20.0f);
251  EXPECT_EQ(rect.GetHeight(), min);
252  EXPECT_TRUE(rect.IsEmpty());
253  EXPECT_TRUE(rect.IsFinite());
254  }
255 
256  {
257  Rect rect = Rect::MakeXYWH(5.0f, min, 20.0f, min);
258 
259  EXPECT_EQ(rect.GetLeft(), 5.0f);
260  EXPECT_EQ(rect.GetTop(), min);
261  EXPECT_EQ(rect.GetRight(), 25.0f);
262  EXPECT_EQ(rect.GetBottom(), -inf);
263  EXPECT_EQ(rect.GetX(), 5.0f);
264  EXPECT_EQ(rect.GetY(), min);
265  EXPECT_EQ(rect.GetWidth(), 20.0f);
266  EXPECT_EQ(rect.GetHeight(), -inf);
267  EXPECT_TRUE(rect.IsEmpty());
268  EXPECT_FALSE(rect.IsFinite());
269  }
270 }

References impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetTop(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetY(), impeller::TRect< T >::IsEmpty(), impeller::TRect< T >::IsFinite(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [300/370]

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

Definition at line 2826 of file rect_unittests.cc.

2826  {
2827  {
2828  auto r = Rect::MakeLTRB(-100, -100, 100, 100);
2829  auto actual = r.Project(r);
2830  auto expected = Rect::MakeLTRB(0, 0, 1, 1);
2831  EXPECT_RECT_NEAR(expected, actual);
2832  }
2833  {
2834  auto r = Rect::MakeLTRB(-100, -100, 100, 100);
2835  auto actual = r.Project(Rect::MakeLTRB(0, 0, 100, 100));
2836  auto expected = Rect::MakeLTRB(0.5, 0.5, 1, 1);
2837  EXPECT_RECT_NEAR(expected, actual);
2838  }
2839 }

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

◆ TEST() [301/370]

impeller::testing::TEST ( RectTest  ,
RectRoundOut   
)

Definition at line 2841 of file rect_unittests.cc.

2841  {
2842  {
2843  auto r = Rect::MakeLTRB(-100, -100, 100, 100);
2844  EXPECT_EQ(Rect::RoundOut(r), r);
2845  }
2846  {
2847  auto r = Rect::MakeLTRB(-100.1, -100.1, 100.1, 100.1);
2848  EXPECT_EQ(Rect::RoundOut(r), Rect::MakeLTRB(-101, -101, 101, 101));
2849  }
2850 }

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

◆ TEST() [302/370]

impeller::testing::TEST ( RectTest  ,
RectRoundOutEmpty   
)

Definition at line 709 of file rect_unittests.cc.

709  {
710  Rect rect;
711 
712  EXPECT_EQ(Rect::RoundOut(rect), Rect());
713 
714  EXPECT_EQ(IRect::RoundOut(rect), IRect());
715 }

References impeller::TRect< Scalar >::RoundOut(), and impeller::TRect< int64_t >::RoundOut().

◆ TEST() [303/370]

impeller::testing::TEST ( RectTest  ,
RectRoundOutSimple   
)

Definition at line 717 of file rect_unittests.cc.

717  {
718  Rect rect = Rect::MakeLTRB(5.125f, 10.75f, 20.625f, 25.375f);
719 
720  EXPECT_EQ(Rect::RoundOut(rect), Rect::MakeLTRB(5.0f, 10.0f, 21.0f, 26.0f));
721 
722  EXPECT_EQ(IRect::RoundOut(rect), IRect::MakeLTRB(5, 10, 21, 26));
723 }

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

◆ TEST() [304/370]

impeller::testing::TEST ( RectTest  ,
RectRoundOutToIRectHuge   
)

Definition at line 725 of file rect_unittests.cc.

725  {
726  auto test = [](int corners) {
727  EXPECT_TRUE(corners >= 0 && corners <= 0xf);
728  Scalar l, t, r, b;
729  int64_t il, it, ir, ib;
730  l = il = 50;
731  t = it = 50;
732  r = ir = 80;
733  b = ib = 80;
734  if ((corners & (1 << 0)) != 0) {
735  l = -1E20;
736  il = std::numeric_limits<int64_t>::min();
737  }
738  if ((corners & (1 << 1)) != 0) {
739  t = -1E20;
740  it = std::numeric_limits<int64_t>::min();
741  }
742  if ((corners & (1 << 2)) != 0) {
743  r = +1E20;
744  ir = std::numeric_limits<int64_t>::max();
745  }
746  if ((corners & (1 << 3)) != 0) {
747  b = +1E20;
748  ib = std::numeric_limits<int64_t>::max();
749  }
750 
751  Rect rect = Rect::MakeLTRB(l, t, r, b);
752  IRect irect = IRect::RoundOut(rect);
753  EXPECT_EQ(irect.GetLeft(), il) << corners;
754  EXPECT_EQ(irect.GetTop(), it) << corners;
755  EXPECT_EQ(irect.GetRight(), ir) << corners;
756  EXPECT_EQ(irect.GetBottom(), ib) << corners;
757  };
758 
759  for (int corners = 0; corners <= 15; corners++) {
760  test(corners);
761  }
762 }

References impeller::saturated::b, impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetTop(), impeller::TRect< Scalar >::MakeLTRB(), and impeller::TRect< int64_t >::RoundOut().

◆ TEST() [305/370]

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

Definition at line 884 of file rect_unittests.cc.

884  {
885  auto test1 = [](Rect rect, Scalar scale) {
886  Rect expected = Rect::MakeXYWH(rect.GetX() * scale, //
887  rect.GetY() * scale, //
888  rect.GetWidth() * scale, //
889  rect.GetHeight() * scale);
890 
891  EXPECT_RECT_NEAR(rect.Scale(scale), expected) //
892  << rect << " * " << scale;
893  EXPECT_RECT_NEAR(rect.Scale(scale, scale), expected) //
894  << rect << " * " << scale;
895  EXPECT_RECT_NEAR(rect.Scale(Point(scale, scale)), expected) //
896  << rect << " * " << scale;
897  EXPECT_RECT_NEAR(rect.Scale(Size(scale, scale)), expected) //
898  << rect << " * " << scale;
899  };
900 
901  auto test2 = [&test1](Rect rect, Scalar scale_x, Scalar scale_y) {
902  Rect expected = Rect::MakeXYWH(rect.GetX() * scale_x, //
903  rect.GetY() * scale_y, //
904  rect.GetWidth() * scale_x, //
905  rect.GetHeight() * scale_y);
906 
907  EXPECT_RECT_NEAR(rect.Scale(scale_x, scale_y), expected) //
908  << rect << " * " << scale_x << ", " << scale_y;
909  EXPECT_RECT_NEAR(rect.Scale(Point(scale_x, scale_y)), expected) //
910  << rect << " * " << scale_x << ", " << scale_y;
911  EXPECT_RECT_NEAR(rect.Scale(Size(scale_x, scale_y)), expected) //
912  << rect << " * " << scale_x << ", " << scale_y;
913 
914  test1(rect, scale_x);
915  test1(rect, scale_y);
916  };
917 
918  test2(Rect::MakeLTRB(10, 15, 100, 150), 1.0, 0.0);
919  test2(Rect::MakeLTRB(10, 15, 100, 150), 0.0, 1.0);
920  test2(Rect::MakeLTRB(10, 15, 100, 150), 0.0, 0.0);
921  test2(Rect::MakeLTRB(10, 15, 100, 150), 2.5, 3.5);
922  test2(Rect::MakeLTRB(10, 15, 100, 150), 3.5, 2.5);
923  test2(Rect::MakeLTRB(10, 15, -100, 150), 2.5, 3.5);
924  test2(Rect::MakeLTRB(10, 15, 100, -150), 2.5, 3.5);
925  test2(Rect::MakeLTRB(10, 15, 100, 150), -2.5, 3.5);
926  test2(Rect::MakeLTRB(10, 15, 100, 150), 2.5, -3.5);
927 }

References EXPECT_RECT_NEAR, impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetY(), impeller::TRect< Scalar >::MakeLTRB(), impeller::TRect< Scalar >::MakeXYWH(), impeller::TRect< T >::Scale(), and scale.

◆ TEST() [306/370]

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

Definition at line 2765 of file rect_unittests.cc.

2765  {
2766  auto r = Rect::MakeLTRB(0, 0, 100, 100);
2767 
2768  EXPECT_EQ(r.Shift(Point(10, 5)), Rect::MakeLTRB(10, 5, 110, 105));
2769  EXPECT_EQ(r.Shift(Point(-10, -5)), Rect::MakeLTRB(-10, -5, 90, 95));
2770 }

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

◆ TEST() [307/370]

impeller::testing::TEST ( RectTest  ,
RectSimpleLTRB   
)

Definition at line 73 of file rect_unittests.cc.

73  {
74  // Using fractional-power-of-2 friendly values for equality tests
75  Rect rect = Rect::MakeLTRB(5.125f, 10.25f, 20.625f, 25.375f);
76 
77  EXPECT_EQ(rect.GetLeft(), 5.125f);
78  EXPECT_EQ(rect.GetTop(), 10.25f);
79  EXPECT_EQ(rect.GetRight(), 20.625f);
80  EXPECT_EQ(rect.GetBottom(), 25.375f);
81  EXPECT_EQ(rect.GetX(), 5.125f);
82  EXPECT_EQ(rect.GetY(), 10.25f);
83  EXPECT_EQ(rect.GetWidth(), 15.5f);
84  EXPECT_EQ(rect.GetHeight(), 15.125f);
85  EXPECT_FALSE(rect.IsEmpty());
86  EXPECT_TRUE(rect.IsFinite());
87 }

References impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetTop(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetY(), impeller::TRect< T >::IsEmpty(), impeller::TRect< T >::IsFinite(), and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST() [308/370]

impeller::testing::TEST ( RectTest  ,
RectSimpleXYWH   
)

Definition at line 103 of file rect_unittests.cc.

103  {
104  // Using fractional-power-of-2 friendly values for equality tests
105  Rect rect = Rect::MakeXYWH(5.125f, 10.25f, 15.5f, 15.125f);
106 
107  EXPECT_EQ(rect.GetLeft(), 5.125f);
108  EXPECT_EQ(rect.GetTop(), 10.25f);
109  EXPECT_EQ(rect.GetRight(), 20.625f);
110  EXPECT_EQ(rect.GetBottom(), 25.375f);
111  EXPECT_EQ(rect.GetX(), 5.125f);
112  EXPECT_EQ(rect.GetY(), 10.25f);
113  EXPECT_EQ(rect.GetWidth(), 15.5f);
114  EXPECT_EQ(rect.GetHeight(), 15.125f);
115  EXPECT_FALSE(rect.IsEmpty());
116  EXPECT_TRUE(rect.IsFinite());
117 }

References impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetTop(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetY(), impeller::TRect< T >::IsEmpty(), impeller::TRect< T >::IsFinite(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [309/370]

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

Definition at line 1313 of file rect_unittests.cc.

1313  {
1314  auto check_nans = [](const Rect& a, const Rect& b, const std::string& label) {
1315  ASSERT_TRUE(a.IsFinite()) << label;
1316  ASSERT_TRUE(b.IsFinite()) << label;
1317  ASSERT_FALSE(a.Union(b).IsEmpty());
1318 
1319  for (int i = 1; i < 16; i++) {
1320  // NaN in a produces b
1321  EXPECT_EQ(swap_nan(a, i).Union(b), b) << label << ", index = " << i;
1322  // NaN in b produces a
1323  EXPECT_EQ(a.Union(swap_nan(b, i)), a) << label << ", index = " << i;
1324  // NaN in both is empty
1325  for (int j = 1; j < 16; j++) {
1326  EXPECT_TRUE(swap_nan(a, i).Union(swap_nan(b, j)).IsEmpty())
1327  << label << ", indices = " << i << ", " << j;
1328  }
1329  }
1330  };
1331 
1332  auto check_empty_flips = [](const Rect& a, const Rect& b,
1333  const std::string& label) {
1334  ASSERT_FALSE(a.IsEmpty());
1335  // b is allowed to be empty
1336 
1337  // unflipped a vs flipped (empty) b yields a
1338  EXPECT_EQ(a.Union(flip_lr(b)), a) << label;
1339  EXPECT_EQ(a.Union(flip_tb(b)), a) << label;
1340  EXPECT_EQ(a.Union(flip_lrtb(b)), a) << label;
1341 
1342  // flipped (empty) a vs unflipped b yields b
1343  EXPECT_EQ(flip_lr(a).Union(b), b) << label;
1344  EXPECT_EQ(flip_tb(a).Union(b), b) << label;
1345  EXPECT_EQ(flip_lrtb(a).Union(b), b) << label;
1346 
1347  // flipped (empty) a vs flipped (empty) b yields empty
1348  EXPECT_TRUE(flip_lr(a).Union(flip_lr(b)).IsEmpty()) << label;
1349  EXPECT_TRUE(flip_tb(a).Union(flip_tb(b)).IsEmpty()) << label;
1350  EXPECT_TRUE(flip_lrtb(a).Union(flip_lrtb(b)).IsEmpty()) << label;
1351  };
1352 
1353  auto test = [&check_nans, &check_empty_flips](const Rect& a, const Rect& b,
1354  const Rect& result) {
1355  ASSERT_FALSE(a.IsEmpty()) << a;
1356  // b is allowed to be empty
1357 
1358  std::stringstream stream;
1359  stream << a << " union " << b;
1360  auto label = stream.str();
1361 
1362  EXPECT_EQ(a.Union(b), result) << label;
1363  EXPECT_EQ(b.Union(a), result) << label;
1364  check_empty_flips(a, b, label);
1365  check_nans(a, b, label);
1366  };
1367 
1368  {
1369  auto a = Rect::MakeXYWH(100, 100, 100, 100);
1370  auto b = Rect::MakeXYWH(0, 0, 0, 0);
1371  auto expected = Rect::MakeXYWH(100, 100, 100, 100);
1372  test(a, b, expected);
1373  }
1374 
1375  {
1376  auto a = Rect::MakeXYWH(100, 100, 100, 100);
1377  auto b = Rect::MakeXYWH(0, 0, 1, 1);
1378  auto expected = Rect::MakeXYWH(0, 0, 200, 200);
1379  test(a, b, expected);
1380  }
1381 
1382  {
1383  auto a = Rect::MakeXYWH(100, 100, 100, 100);
1384  auto b = Rect::MakeXYWH(10, 10, 1, 1);
1385  auto expected = Rect::MakeXYWH(10, 10, 190, 190);
1386  test(a, b, expected);
1387  }
1388 
1389  {
1390  auto a = Rect::MakeXYWH(0, 0, 100, 100);
1391  auto b = Rect::MakeXYWH(10, 10, 100, 100);
1392  auto expected = Rect::MakeXYWH(0, 0, 110, 110);
1393  test(a, b, expected);
1394  }
1395 
1396  {
1397  auto a = Rect::MakeXYWH(0, 0, 100, 100);
1398  auto b = Rect::MakeXYWH(100, 100, 100, 100);
1399  auto expected = Rect::MakeXYWH(0, 0, 200, 200);
1400  test(a, b, expected);
1401  }
1402 }

References impeller::saturated::b, flip_lr(), flip_lrtb(), flip_tb(), impeller::TRect< T >::IsEmpty(), impeller::TRect< T >::IsFinite(), impeller::TRect< Scalar >::MakeXYWH(), swap_nan(), and impeller::TRect< T >::Union().

◆ TEST() [310/370]

impeller::testing::TEST ( RectTest  ,
RectXYWHIsEmpty   
)

Definition at line 1127 of file rect_unittests.cc.

1127  {
1128  auto nan = std::numeric_limits<Scalar>::quiet_NaN();
1129 
1130  // Non-empty
1131  EXPECT_FALSE(Rect::MakeXYWH(1.5, 2.3, 10.5, 7.2).IsEmpty());
1132 
1133  // Empty both width and height both 0 or negative, in all combinations
1134  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, 0.0, 0.0).IsEmpty());
1135  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, -1.0, -1.0).IsEmpty());
1136  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, 0.0, -1.0).IsEmpty());
1137  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, -1.0, 0.0).IsEmpty());
1138 
1139  // Empty for 0 or negative width or height (but not both at the same time)
1140  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, 10.5, 0.0).IsEmpty());
1141  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, 10.5, -1.0).IsEmpty());
1142  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, 0.0, 7.2).IsEmpty());
1143  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, -1.0, 7.2).IsEmpty());
1144 
1145  // Empty for NaN in width or height or both
1146  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, 10.5, nan).IsEmpty());
1147  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, nan, 7.2).IsEmpty());
1148  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, nan, nan).IsEmpty());
1149 }

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

◆ TEST() [311/370]

impeller::testing::TEST ( RenderPassBuilder  ,
CreatesMSAAResolveWithCorrectStore   
)

Definition at line 102 of file render_pass_builder_vk_unittests.cc.

102  {
103  RenderPassBuilderVK builder = RenderPassBuilderVK();
104  auto const context = MockVulkanContextBuilder().Build();
105 
106  // Create an MSAA color attachment.
107  builder.SetColorAttachment(0, PixelFormat::kR8G8B8A8UNormInt,
108  SampleCount::kCount4, LoadAction::kClear,
109  StoreAction::kMultisampleResolve);
110 
111  auto render_pass = builder.Build(context->GetDevice());
112 
113  EXPECT_TRUE(!!render_pass);
114 
115  auto maybe_color = builder.GetColorAttachments().find(0u);
116  ASSERT_NE(maybe_color, builder.GetColorAttachments().end());
117  auto color = maybe_color->second;
118 
119  // MSAA Texture.
120  EXPECT_EQ(color.initialLayout, vk::ImageLayout::eGeneral);
121  EXPECT_EQ(color.finalLayout, vk::ImageLayout::eGeneral);
122  EXPECT_EQ(color.loadOp, vk::AttachmentLoadOp::eClear);
123  EXPECT_EQ(color.storeOp, vk::AttachmentStoreOp::eDontCare);
124 
125  auto maybe_resolve = builder.GetResolves().find(0u);
126  ASSERT_NE(maybe_resolve, builder.GetResolves().end());
127  auto resolve = maybe_resolve->second;
128 
129  // MSAA Resolve Texture.
130  EXPECT_EQ(resolve.initialLayout, vk::ImageLayout::eGeneral);
131  EXPECT_EQ(resolve.finalLayout, vk::ImageLayout::eGeneral);
132  EXPECT_EQ(resolve.loadOp, vk::AttachmentLoadOp::eClear);
133  EXPECT_EQ(resolve.storeOp, vk::AttachmentStoreOp::eStore);
134 }

References impeller::RenderPassBuilderVK::Build(), impeller::RenderPassBuilderVK::GetColorAttachments(), impeller::RenderPassBuilderVK::GetResolves(), impeller::kClear, impeller::kCount4, impeller::kMultisampleResolve, impeller::kR8G8B8A8UNormInt, and impeller::RenderPassBuilderVK::SetColorAttachment().

◆ TEST() [312/370]

impeller::testing::TEST ( RenderPassBuilder  ,
CreatesRenderPassWithCombinedDepthStencil   
)

Definition at line 30 of file render_pass_builder_vk_unittests.cc.

30  {
31  RenderPassBuilderVK builder = RenderPassBuilderVK();
32  auto const context = MockVulkanContextBuilder().Build();
33 
34  // Create a single color attachment with a transient depth stencil.
35  builder.SetColorAttachment(0, PixelFormat::kR8G8B8A8UNormInt,
36  SampleCount::kCount1, LoadAction::kClear,
37  StoreAction::kStore);
38  builder.SetDepthStencilAttachment(PixelFormat::kD24UnormS8Uint,
39  SampleCount::kCount1, LoadAction::kDontCare,
40  StoreAction::kDontCare);
41 
42  auto render_pass = builder.Build(context->GetDevice());
43 
44  EXPECT_TRUE(!!render_pass);
45 
46  auto maybe_color = builder.GetColorAttachments().find(0u);
47  ASSERT_NE(maybe_color, builder.GetColorAttachments().end());
48  auto color = maybe_color->second;
49 
50  EXPECT_EQ(color.initialLayout, vk::ImageLayout::eGeneral);
51  EXPECT_EQ(color.finalLayout, vk::ImageLayout::eGeneral);
52  EXPECT_EQ(color.loadOp, vk::AttachmentLoadOp::eClear);
53  EXPECT_EQ(color.storeOp, vk::AttachmentStoreOp::eStore);
54 
55  auto maybe_depth_stencil = builder.GetDepthStencil();
56  ASSERT_TRUE(maybe_depth_stencil.has_value());
57  if (!maybe_depth_stencil.has_value()) {
58  return;
59  }
60  auto depth_stencil = maybe_depth_stencil.value();
61 
62  EXPECT_EQ(depth_stencil.initialLayout, vk::ImageLayout::eUndefined);
63  EXPECT_EQ(depth_stencil.finalLayout,
64  vk::ImageLayout::eDepthStencilAttachmentOptimal);
65  EXPECT_EQ(depth_stencil.loadOp, vk::AttachmentLoadOp::eDontCare);
66  EXPECT_EQ(depth_stencil.storeOp, vk::AttachmentStoreOp::eDontCare);
67  EXPECT_EQ(depth_stencil.stencilLoadOp, vk::AttachmentLoadOp::eDontCare);
68  EXPECT_EQ(depth_stencil.stencilStoreOp, vk::AttachmentStoreOp::eDontCare);
69 }

References impeller::RenderPassBuilderVK::Build(), impeller::RenderPassBuilderVK::GetColorAttachments(), impeller::RenderPassBuilderVK::GetDepthStencil(), impeller::kClear, impeller::kCount1, impeller::kD24UnormS8Uint, impeller::kDontCare, impeller::kR8G8B8A8UNormInt, impeller::kStore, impeller::RenderPassBuilderVK::SetColorAttachment(), and impeller::RenderPassBuilderVK::SetDepthStencilAttachment().

◆ TEST() [313/370]

impeller::testing::TEST ( RenderPassBuilder  ,
CreatesRenderPassWithNoDepthStencil   
)

Definition at line 15 of file render_pass_builder_vk_unittests.cc.

15  {
16  RenderPassBuilderVK builder = RenderPassBuilderVK();
17  auto const context = MockVulkanContextBuilder().Build();
18 
19  // Create a single color attachment with a transient depth stencil.
20  builder.SetColorAttachment(0, PixelFormat::kR8G8B8A8UNormInt,
21  SampleCount::kCount1, LoadAction::kClear,
22  StoreAction::kStore);
23 
24  auto render_pass = builder.Build(context->GetDevice());
25 
26  EXPECT_TRUE(!!render_pass);
27  EXPECT_FALSE(builder.GetDepthStencil().has_value());
28 }

References impeller::RenderPassBuilderVK::Build(), impeller::RenderPassBuilderVK::GetDepthStencil(), impeller::kClear, impeller::kCount1, impeller::kR8G8B8A8UNormInt, impeller::kStore, and impeller::RenderPassBuilderVK::SetColorAttachment().

◆ TEST() [314/370]

impeller::testing::TEST ( RenderPassBuilder  ,
CreatesRenderPassWithOnlyStencil   
)

Definition at line 71 of file render_pass_builder_vk_unittests.cc.

71  {
72  RenderPassBuilderVK builder = RenderPassBuilderVK();
73  auto const context = MockVulkanContextBuilder().Build();
74 
75  // Create a single color attachment with a transient depth stencil.
76  builder.SetColorAttachment(0, PixelFormat::kR8G8B8A8UNormInt,
77  SampleCount::kCount1, LoadAction::kClear,
78  StoreAction::kStore);
79  builder.SetStencilAttachment(PixelFormat::kS8UInt, SampleCount::kCount1,
80  LoadAction::kDontCare, StoreAction::kDontCare);
81 
82  auto render_pass = builder.Build(context->GetDevice());
83 
84  EXPECT_TRUE(!!render_pass);
85 
86  auto maybe_depth_stencil = builder.GetDepthStencil();
87  ASSERT_TRUE(maybe_depth_stencil.has_value());
88  if (!maybe_depth_stencil.has_value()) {
89  return;
90  }
91  auto depth_stencil = maybe_depth_stencil.value();
92 
93  EXPECT_EQ(depth_stencil.initialLayout, vk::ImageLayout::eUndefined);
94  EXPECT_EQ(depth_stencil.finalLayout,
95  vk::ImageLayout::eDepthStencilAttachmentOptimal);
96  EXPECT_EQ(depth_stencil.loadOp, vk::AttachmentLoadOp::eDontCare);
97  EXPECT_EQ(depth_stencil.storeOp, vk::AttachmentStoreOp::eDontCare);
98  EXPECT_EQ(depth_stencil.stencilLoadOp, vk::AttachmentLoadOp::eDontCare);
99  EXPECT_EQ(depth_stencil.stencilStoreOp, vk::AttachmentStoreOp::eDontCare);
100 }

References impeller::RenderPassBuilderVK::Build(), impeller::RenderPassBuilderVK::GetDepthStencil(), impeller::kClear, impeller::kCount1, impeller::kDontCare, impeller::kR8G8B8A8UNormInt, impeller::kS8UInt, impeller::kStore, impeller::RenderPassBuilderVK::SetColorAttachment(), and impeller::RenderPassBuilderVK::SetStencilAttachment().

◆ TEST() [315/370]

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::saturated::b, and impeller::ResourceManagerVK::Create().

◆ TEST() [316/370]

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

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

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

impeller::testing::TEST ( SaturatedMath  ,
CastingFiniteDoubleToFloatStaysFinite   
)

Definition at line 981 of file saturated_math_unittests.cc.

981  {
982  const double d_max = std::numeric_limits<double>::max();
983  const float f_max = std::numeric_limits<float>::max();
984 
985  {
986  const float result = saturated::Cast<double, float>(d_max);
987  EXPECT_EQ(result, f_max);
988  }
989 
990  {
991  const float result = saturated::Cast<double, float>(-d_max);
992  EXPECT_EQ(result, -f_max);
993  }
994 }

◆ TEST() [320/370]

impeller::testing::TEST ( SaturatedMath  ,
CastingInfiniteDoubleToFloatStaysInfinite   
)

Definition at line 996 of file saturated_math_unittests.cc.

996  {
997  const double d_inf = std::numeric_limits<double>::infinity();
998  const float f_max = std::numeric_limits<float>::infinity();
999 
1000  {
1001  const float result = saturated::Cast<double, float>(d_inf);
1002  EXPECT_EQ(result, f_max);
1003  }
1004 
1005  {
1006  const float result = saturated::Cast<double, float>(-d_inf);
1007  EXPECT_EQ(result, -f_max);
1008  }
1009 }

◆ TEST() [321/370]

impeller::testing::TEST ( SaturatedMath  ,
CastingInfiniteScalarToSignedIntProducesLimit   
)

Definition at line 1066 of file saturated_math_unittests.cc.

1066  {
1067  // larger than even any [u]int64_t;
1068  const Scalar inf = std::numeric_limits<Scalar>::infinity();
1069 
1070  {
1071  const auto result = saturated::Cast<Scalar, int8_t>(inf);
1072  EXPECT_EQ(result, int8_t(0x7F));
1073  }
1074  {
1075  const auto result = saturated::Cast<Scalar, int8_t>(-inf);
1076  EXPECT_EQ(result, int8_t(0x80));
1077  }
1078 
1079  {
1080  const auto result = saturated::Cast<Scalar, int16_t>(inf);
1081  EXPECT_EQ(result, int16_t(0x7FFF));
1082  }
1083  {
1084  const auto result = saturated::Cast<Scalar, int16_t>(-inf);
1085  EXPECT_EQ(result, int16_t(0x8000));
1086  }
1087 
1088  {
1089  const auto result = saturated::Cast<Scalar, int32_t>(inf);
1090  EXPECT_EQ(result, int32_t(0x7FFFFFFF));
1091  }
1092  {
1093  const auto result = saturated::Cast<Scalar, int32_t>(-inf);
1094  EXPECT_EQ(result, int32_t(0x80000000));
1095  }
1096 
1097  {
1098  const auto result = saturated::Cast<Scalar, int64_t>(inf);
1099  EXPECT_EQ(result, int64_t(0x7FFFFFFFFFFFFFFF));
1100  }
1101  {
1102  const auto result = saturated::Cast<Scalar, int64_t>(-inf);
1103  EXPECT_EQ(result, int64_t(0x8000000000000000));
1104  }
1105 }

◆ TEST() [322/370]

impeller::testing::TEST ( SaturatedMath  ,
CastingLargeScalarToSignedIntProducesLimit   
)

Definition at line 1025 of file saturated_math_unittests.cc.

1025  {
1026  // larger than even any [u]int64_t;
1027  const Scalar large = 1e20f;
1028 
1029  {
1030  const auto result = saturated::Cast<Scalar, int8_t>(large);
1031  EXPECT_EQ(result, int8_t(0x7F));
1032  }
1033  {
1034  const auto result = saturated::Cast<Scalar, int8_t>(-large);
1035  EXPECT_EQ(result, int8_t(0x80));
1036  }
1037 
1038  {
1039  const auto result = saturated::Cast<Scalar, int16_t>(large);
1040  EXPECT_EQ(result, int16_t(0x7FFF));
1041  }
1042  {
1043  const auto result = saturated::Cast<Scalar, int16_t>(-large);
1044  EXPECT_EQ(result, int16_t(0x8000));
1045  }
1046 
1047  {
1048  const auto result = saturated::Cast<Scalar, int32_t>(large);
1049  EXPECT_EQ(result, int32_t(0x7FFFFFFF));
1050  }
1051  {
1052  const auto result = saturated::Cast<Scalar, int32_t>(-large);
1053  EXPECT_EQ(result, int32_t(0x80000000));
1054  }
1055 
1056  {
1057  const auto result = saturated::Cast<Scalar, int64_t>(large);
1058  EXPECT_EQ(result, int64_t(0x7FFFFFFFFFFFFFFF));
1059  }
1060  {
1061  const auto result = saturated::Cast<Scalar, int64_t>(-large);
1062  EXPECT_EQ(result, int64_t(0x8000000000000000));
1063  }
1064 }

◆ TEST() [323/370]

impeller::testing::TEST ( SaturatedMath  ,
CastingNaNDoubleToFloatStaysNaN   
)

Definition at line 1011 of file saturated_math_unittests.cc.

1011  {
1012  const double d_nan = std::numeric_limits<double>::quiet_NaN();
1013 
1014  {
1015  const float result = saturated::Cast<double, float>(d_nan);
1016  EXPECT_TRUE(std::isnan(result));
1017  }
1018 
1019  {
1020  const float result = saturated::Cast<double, float>(-d_nan);
1021  EXPECT_TRUE(std::isnan(result));
1022  }
1023 }

◆ TEST() [324/370]

impeller::testing::TEST ( SaturatedMath  ,
CastingNaNScalarToSignedIntProducesZero   
)

Definition at line 1107 of file saturated_math_unittests.cc.

1107  {
1108  // larger than even any [u]int64_t;
1109  const Scalar nan = std::numeric_limits<Scalar>::quiet_NaN();
1110 
1111  {
1112  const auto result = saturated::Cast<Scalar, int8_t>(nan);
1113  EXPECT_EQ(result, int8_t(0));
1114  }
1115 
1116  {
1117  const auto result = saturated::Cast<Scalar, int16_t>(nan);
1118  EXPECT_EQ(result, int16_t(0));
1119  }
1120 
1121  {
1122  const auto result = saturated::Cast<Scalar, int32_t>(nan);
1123  EXPECT_EQ(result, int32_t(0));
1124  }
1125 
1126  {
1127  const auto result = saturated::Cast<Scalar, int64_t>(nan);
1128  EXPECT_EQ(result, int64_t(0));
1129  }
1130 }

◆ TEST() [325/370]

impeller::testing::TEST ( SaturatedMath  ,
ExplicitAddOfFloatingPoint   
)

Definition at line 136 of file saturated_math_unittests.cc.

136  {
137  {
138  const float inf = std::numeric_limits<float>::infinity();
139  const float max = std::numeric_limits<float>::max();
140  const float big = max * 0.5f;
141 
142  EXPECT_EQ(saturated::Add<float>(big, big), max);
143  EXPECT_EQ(saturated::Add<float>(max, big), inf);
144  EXPECT_EQ(saturated::Add<float>(big, max), inf);
145  EXPECT_EQ(saturated::Add<float>(max, max), inf);
146  EXPECT_EQ(saturated::Add<float>(max, inf), inf);
147  EXPECT_EQ(saturated::Add<float>(inf, max), inf);
148  EXPECT_EQ(saturated::Add<float>(inf, inf), inf);
149 
150  EXPECT_EQ(saturated::Add<float>(-big, -big), -max);
151  EXPECT_EQ(saturated::Add<float>(-max, -big), -inf);
152  EXPECT_EQ(saturated::Add<float>(-big, -max), -inf);
153  EXPECT_EQ(saturated::Add<float>(-max, -max), -inf);
154  EXPECT_EQ(saturated::Add<float>(-max, -inf), -inf);
155  EXPECT_EQ(saturated::Add<float>(-inf, -max), -inf);
156  EXPECT_EQ(saturated::Add<float>(-inf, -inf), -inf);
157 
158  EXPECT_EQ(saturated::Add<float>(big, -big), 0.0f);
159  EXPECT_EQ(saturated::Add<float>(max, -big), big);
160  EXPECT_EQ(saturated::Add<float>(big, -max), -big);
161  EXPECT_EQ(saturated::Add<float>(max, -max), 0.0f);
162  EXPECT_EQ(saturated::Add<float>(max, -inf), -inf);
163  EXPECT_EQ(saturated::Add<float>(inf, -max), inf);
164  EXPECT_TRUE(std::isnan(saturated::Add<float>(inf, -inf)));
165 
166  EXPECT_EQ(saturated::Add<float>(-big, big), 0.0f);
167  EXPECT_EQ(saturated::Add<float>(-max, big), -big);
168  EXPECT_EQ(saturated::Add<float>(-big, max), big);
169  EXPECT_EQ(saturated::Add<float>(-max, max), 0.0f);
170  EXPECT_EQ(saturated::Add<float>(-max, inf), inf);
171  EXPECT_EQ(saturated::Add<float>(-inf, max), -inf);
172  EXPECT_TRUE(std::isnan(saturated::Add<float>(-inf, inf)));
173  }
174  {
175  const double inf = std::numeric_limits<double>::infinity();
176  const double max = std::numeric_limits<double>::max();
177  const double big = max * 0.5f;
178 
179  EXPECT_EQ(saturated::Add<double>(big, big), max);
180  EXPECT_EQ(saturated::Add<double>(max, big), inf);
181  EXPECT_EQ(saturated::Add<double>(big, max), inf);
182  EXPECT_EQ(saturated::Add<double>(max, max), inf);
183  EXPECT_EQ(saturated::Add<double>(max, inf), inf);
184  EXPECT_EQ(saturated::Add<double>(inf, max), inf);
185  EXPECT_EQ(saturated::Add<double>(inf, inf), inf);
186 
187  EXPECT_EQ(saturated::Add<double>(-big, -big), -max);
188  EXPECT_EQ(saturated::Add<double>(-max, -big), -inf);
189  EXPECT_EQ(saturated::Add<double>(-big, -max), -inf);
190  EXPECT_EQ(saturated::Add<double>(-max, -max), -inf);
191  EXPECT_EQ(saturated::Add<double>(-max, -inf), -inf);
192  EXPECT_EQ(saturated::Add<double>(-inf, -max), -inf);
193  EXPECT_EQ(saturated::Add<double>(-inf, -inf), -inf);
194 
195  EXPECT_EQ(saturated::Add<double>(big, -big), 0.0f);
196  EXPECT_EQ(saturated::Add<double>(max, -big), big);
197  EXPECT_EQ(saturated::Add<double>(big, -max), -big);
198  EXPECT_EQ(saturated::Add<double>(max, -max), 0.0f);
199  EXPECT_EQ(saturated::Add<double>(max, -inf), -inf);
200  EXPECT_EQ(saturated::Add<double>(inf, -max), inf);
201  EXPECT_TRUE(std::isnan(saturated::Add<double>(inf, -inf)));
202 
203  EXPECT_EQ(saturated::Add<double>(-big, big), 0.0f);
204  EXPECT_EQ(saturated::Add<double>(-max, big), -big);
205  EXPECT_EQ(saturated::Add<double>(-big, max), big);
206  EXPECT_EQ(saturated::Add<double>(-max, max), 0.0f);
207  EXPECT_EQ(saturated::Add<double>(-max, inf), inf);
208  EXPECT_EQ(saturated::Add<double>(-inf, max), -inf);
209  EXPECT_TRUE(std::isnan(saturated::Add<double>(-inf, inf)));
210  }
211  {
212  const Scalar inf = std::numeric_limits<Scalar>::infinity();
213  const Scalar max = std::numeric_limits<Scalar>::max();
214  const Scalar big = max * 0.5f;
215 
216  EXPECT_EQ(saturated::Add<Scalar>(big, big), max);
217  EXPECT_EQ(saturated::Add<Scalar>(max, big), inf);
218  EXPECT_EQ(saturated::Add<Scalar>(big, max), inf);
219  EXPECT_EQ(saturated::Add<Scalar>(max, max), inf);
220  EXPECT_EQ(saturated::Add<Scalar>(max, inf), inf);
221  EXPECT_EQ(saturated::Add<Scalar>(inf, max), inf);
222  EXPECT_EQ(saturated::Add<Scalar>(inf, inf), inf);
223 
224  EXPECT_EQ(saturated::Add<Scalar>(-big, -big), -max);
225  EXPECT_EQ(saturated::Add<Scalar>(-max, -big), -inf);
226  EXPECT_EQ(saturated::Add<Scalar>(-big, -max), -inf);
227  EXPECT_EQ(saturated::Add<Scalar>(-max, -max), -inf);
228  EXPECT_EQ(saturated::Add<Scalar>(-max, -inf), -inf);
229  EXPECT_EQ(saturated::Add<Scalar>(-inf, -max), -inf);
230  EXPECT_EQ(saturated::Add<Scalar>(-inf, -inf), -inf);
231 
232  EXPECT_EQ(saturated::Add<Scalar>(big, -big), 0.0f);
233  EXPECT_EQ(saturated::Add<Scalar>(max, -big), big);
234  EXPECT_EQ(saturated::Add<Scalar>(big, -max), -big);
235  EXPECT_EQ(saturated::Add<Scalar>(max, -max), 0.0f);
236  EXPECT_EQ(saturated::Add<Scalar>(max, -inf), -inf);
237  EXPECT_EQ(saturated::Add<Scalar>(inf, -max), inf);
238  EXPECT_TRUE(std::isnan(saturated::Add<Scalar>(inf, -inf)));
239 
240  EXPECT_EQ(saturated::Add<Scalar>(-big, big), 0.0f);
241  EXPECT_EQ(saturated::Add<Scalar>(-max, big), -big);
242  EXPECT_EQ(saturated::Add<Scalar>(-big, max), big);
243  EXPECT_EQ(saturated::Add<Scalar>(-max, max), 0.0f);
244  EXPECT_EQ(saturated::Add<Scalar>(-max, inf), inf);
245  EXPECT_EQ(saturated::Add<Scalar>(-inf, max), -inf);
246  EXPECT_TRUE(std::isnan(saturated::Add<Scalar>(-inf, inf)));
247  }
248 }

◆ TEST() [326/370]

impeller::testing::TEST ( SaturatedMath  ,
ExplicitAddOfSignedInts   
)

Definition at line 12 of file saturated_math_unittests.cc.

12  {
13  {
14  EXPECT_EQ(saturated::Add<int8_t>(0x79, 5), int8_t(0x7E));
15  EXPECT_EQ(saturated::Add<int8_t>(0x7A, 5), int8_t(0x7F));
16  EXPECT_EQ(saturated::Add<int8_t>(0x7B, 5), int8_t(0x7F));
17  }
18  {
19  EXPECT_EQ(saturated::Add<int8_t>(0x86, -5), int8_t(0x81));
20  EXPECT_EQ(saturated::Add<int8_t>(0x85, -5), int8_t(0x80));
21  EXPECT_EQ(saturated::Add<int8_t>(0x84, -5), int8_t(0x80));
22  }
23  {
24  EXPECT_EQ(saturated::Add<int16_t>(0x7FF9, 5), int16_t(0x7FFE));
25  EXPECT_EQ(saturated::Add<int16_t>(0x7FFA, 5), int16_t(0x7FFF));
26  EXPECT_EQ(saturated::Add<int16_t>(0x7FFB, 5), int16_t(0x7FFF));
27  }
28  {
29  EXPECT_EQ(saturated::Add<int16_t>(0x8006, -5), int16_t(0x8001));
30  EXPECT_EQ(saturated::Add<int16_t>(0x8005, -5), int16_t(0x8000));
31  EXPECT_EQ(saturated::Add<int16_t>(0x8004, -5), int16_t(0x8000));
32  }
33  {
34  EXPECT_EQ(saturated::Add<int32_t>(0x7FFFFFF9, 5), int32_t(0x7FFFFFFE));
35  EXPECT_EQ(saturated::Add<int32_t>(0x7FFFFFFA, 5), int32_t(0x7FFFFFFF));
36  EXPECT_EQ(saturated::Add<int32_t>(0x7FFFFFFB, 5), int32_t(0x7FFFFFFF));
37  }
38  {
39  EXPECT_EQ(saturated::Add<int32_t>(0x80000006, -5), int32_t(0x80000001));
40  EXPECT_EQ(saturated::Add<int32_t>(0x80000005, -5), int32_t(0x80000000));
41  EXPECT_EQ(saturated::Add<int32_t>(0x80000004, -5), int32_t(0x80000000));
42  }
43  {
44  EXPECT_EQ(saturated::Add<int64_t>(0x7FFFFFFFFFFFFFF9, 5),
45  int64_t(0x7FFFFFFFFFFFFFFE));
46  EXPECT_EQ(saturated::Add<int64_t>(0x7FFFFFFFFFFFFFFA, 5),
47  int64_t(0x7FFFFFFFFFFFFFFF));
48  EXPECT_EQ(saturated::Add<int64_t>(0x7FFFFFFFFFFFFFFB, 5),
49  int64_t(0x7FFFFFFFFFFFFFFF));
50  }
51  {
52  EXPECT_EQ(saturated::Add<int64_t>(0x8000000000000006, -5),
53  int64_t(0x8000000000000001));
54  EXPECT_EQ(saturated::Add<int64_t>(0x8000000000000005, -5),
55  int64_t(0x8000000000000000));
56  EXPECT_EQ(saturated::Add<int64_t>(0x8000000000000004, -5),
57  int64_t(0x8000000000000000));
58  }
59 }

◆ TEST() [327/370]

impeller::testing::TEST ( SaturatedMath  ,
ExplicitAverageScalarOfFloatingPoint   
)

Definition at line 828 of file saturated_math_unittests.cc.

828  {
829  const Scalar s_inf = std::numeric_limits<Scalar>::infinity();
830  const Scalar s_max = std::numeric_limits<Scalar>::max();
831  const Scalar s_big = s_max * 0.5f;
832 
833  {
834  const float inf = std::numeric_limits<Scalar>::infinity();
835  const float max = std::numeric_limits<float>::max();
836  const float big = max * 0.5f;
837 
838  EXPECT_EQ(saturated::AverageScalar<float>(big, big), s_big);
839  EXPECT_EQ(saturated::AverageScalar<float>(max, max), s_max);
840  EXPECT_EQ(saturated::AverageScalar<float>(big, -big), 0.0f);
841  EXPECT_EQ(saturated::AverageScalar<float>(max, -max), 0.0f);
842  EXPECT_EQ(saturated::AverageScalar<float>(-big, big), 0.0f);
843  EXPECT_EQ(saturated::AverageScalar<float>(-max, max), 0.0f);
844  EXPECT_EQ(saturated::AverageScalar<float>(-big, -big), -s_big);
845  EXPECT_EQ(saturated::AverageScalar<float>(-max, -max), -s_max);
846 
847  EXPECT_EQ(saturated::AverageScalar<float>(inf, inf), s_inf);
848  EXPECT_EQ(saturated::AverageScalar<float>(-inf, -inf), -s_inf);
849  EXPECT_TRUE(std::isnan(saturated::AverageScalar<float>(-inf, inf)));
850  EXPECT_TRUE(std::isnan(saturated::AverageScalar<float>(inf, -inf)));
851  }
852  {
853  const double inf = std::numeric_limits<Scalar>::infinity();
854  const double max = std::numeric_limits<double>::max();
855  const double big = max * 0.5;
856 
857  // Most of the averages below using the double constants will
858  // overflow the Scalar return value and result in infinity,
859  // so we also test with some Scalar constants (promoted to double)
860  // to verify that they don't overflow in the double template
861  EXPECT_EQ(saturated::AverageScalar<double>(s_big, s_big), s_big);
862  EXPECT_EQ(saturated::AverageScalar<double>(s_max, s_max), s_max);
863  EXPECT_EQ(saturated::AverageScalar<double>(-s_big, -s_big), -s_big);
864  EXPECT_EQ(saturated::AverageScalar<double>(-s_max, -s_max), -s_max);
865 
866  // And now testing continues with the double constants which
867  // mostly overflow
868  EXPECT_EQ(saturated::AverageScalar<double>(big, big), s_inf);
869  EXPECT_EQ(saturated::AverageScalar<double>(max, max), s_inf);
870  EXPECT_EQ(saturated::AverageScalar<double>(big, -big), 0.0f);
871  EXPECT_EQ(saturated::AverageScalar<double>(max, -max), 0.0f);
872  EXPECT_EQ(saturated::AverageScalar<double>(-big, big), 0.0f);
873  EXPECT_EQ(saturated::AverageScalar<double>(-max, max), 0.0f);
874  EXPECT_EQ(saturated::AverageScalar<double>(-big, -big), -s_inf);
875  EXPECT_EQ(saturated::AverageScalar<double>(-max, -max), -s_inf);
876 
877  EXPECT_EQ(saturated::AverageScalar<double>(inf, inf), s_inf);
878  EXPECT_EQ(saturated::AverageScalar<double>(-inf, -inf), -s_inf);
879  EXPECT_TRUE(std::isnan(saturated::AverageScalar<double>(-inf, inf)));
880  EXPECT_TRUE(std::isnan(saturated::AverageScalar<double>(inf, -inf)));
881  }
882  {
883  const Scalar inf = std::numeric_limits<Scalar>::infinity();
884  const Scalar max = std::numeric_limits<Scalar>::max();
885  const Scalar big = max * 0.5f;
886 
887  EXPECT_EQ(saturated::AverageScalar<Scalar>(big, big), s_big);
888  EXPECT_EQ(saturated::AverageScalar<Scalar>(max, max), s_max);
889  EXPECT_EQ(saturated::AverageScalar<Scalar>(big, -big), 0.0f);
890  EXPECT_EQ(saturated::AverageScalar<Scalar>(max, -max), 0.0f);
891  EXPECT_EQ(saturated::AverageScalar<Scalar>(-big, big), 0.0f);
892  EXPECT_EQ(saturated::AverageScalar<Scalar>(-max, max), 0.0f);
893  EXPECT_EQ(saturated::AverageScalar<Scalar>(-big, -big), -s_big);
894  EXPECT_EQ(saturated::AverageScalar<Scalar>(-max, -max), -s_max);
895 
896  EXPECT_EQ(saturated::AverageScalar<Scalar>(inf, inf), s_inf);
897  EXPECT_EQ(saturated::AverageScalar<Scalar>(-inf, -inf), -s_inf);
898  EXPECT_TRUE(std::isnan(saturated::AverageScalar<Scalar>(-inf, s_inf)));
899  EXPECT_TRUE(std::isnan(saturated::AverageScalar<Scalar>(inf, -s_inf)));
900  }
901 }

◆ TEST() [328/370]

impeller::testing::TEST ( SaturatedMath  ,
ExplicitAverageScalarOfSignedInts   
)

Definition at line 716 of file saturated_math_unittests.cc.

716  {
717  // For each type try:
718  //
719  // - near the limits, averaging to 0
720  // - at the limits, averaging to 0 or 0.5 depending on precision
721  // - both large enough for the sum to overflow
722  // - both negative enough for the sum to underflow
723  {
724  EXPECT_EQ(saturated::AverageScalar<int8_t>(0x81, 0x7F), -0.0f);
725  EXPECT_EQ(saturated::AverageScalar<int8_t>(0x80, 0x7F), -0.5f);
726  EXPECT_EQ(saturated::AverageScalar<int8_t>(0x70, 0x75), 114.5f);
727  EXPECT_EQ(saturated::AverageScalar<int8_t>(0x85, 0x8A), -120.5f);
728  }
729  {
730  EXPECT_EQ(saturated::AverageScalar<int16_t>(0x8001, 0x7FFF), -0.0f);
731  EXPECT_EQ(saturated::AverageScalar<int16_t>(0x8000, 0x7FFF), -0.5f);
732  EXPECT_EQ(saturated::AverageScalar<int16_t>(0x7000, 0x7005), 28674.5f);
733  EXPECT_EQ(saturated::AverageScalar<int16_t>(0x8005, 0x800A), -32760.5f);
734  }
735  {
736  EXPECT_EQ(saturated::AverageScalar<int32_t>(0x80000001, 0x7FFFFFFF), -0.0f);
737  EXPECT_EQ(saturated::AverageScalar<int32_t>(0x80000000, 0x7FFFFFFF), -0.5f);
738  EXPECT_EQ(saturated::AverageScalar<int32_t>(0x70000000, 0x70000005),
739  1879048195.5f);
740  EXPECT_EQ(saturated::AverageScalar<int32_t>(0x80000005, 0x8000000A),
741  -2147483655.5f);
742  }
743  {
744  EXPECT_EQ(saturated::AverageScalar<int64_t>(0x8000000000000001,
745  0x7FFFFFFFFFFFFFFF),
746  0.0f);
747  // 64-bit integers overflow the ability of a Scalar (float) to
748  // represent discrete integers and so the two numbers we are
749  // averaging here will look like the same number with different
750  // signs and the answer will be "0"
751  EXPECT_EQ(saturated::AverageScalar<int64_t>(0x8000000000000000,
752  0x7FFFFFFFFFFFFFFF),
753  0.0f);
754  EXPECT_NEAR(saturated::AverageScalar<int64_t>(0x7000000000000000,
755  0x7000000000000005),
756  8.07045053e+18, 1e18);
757  EXPECT_NEAR(saturated::AverageScalar<int64_t>(0x8000000000000005,
758  0x800000000000000A),
759  -9.223372e+18, 1e18);
760  }
761 }

◆ TEST() [329/370]

impeller::testing::TEST ( SaturatedMath  ,
ExplicitSubOfFloatingPoint   
)

Definition at line 488 of file saturated_math_unittests.cc.

488  {
489  {
490  const float inf = std::numeric_limits<float>::infinity();
491  const float max = std::numeric_limits<float>::max();
492  const float big = max * 0.5f;
493 
494  EXPECT_EQ(saturated::Sub<float>(big, big), 0.0f);
495  EXPECT_EQ(saturated::Sub<float>(max, big), big);
496  EXPECT_EQ(saturated::Sub<float>(big, max), -big);
497  EXPECT_EQ(saturated::Sub<float>(max, max), 0.0f);
498  EXPECT_EQ(saturated::Sub<float>(max, inf), -inf);
499  EXPECT_EQ(saturated::Sub<float>(inf, max), inf);
500  EXPECT_TRUE(std::isnan(saturated::Sub<float>(inf, inf)));
501 
502  EXPECT_EQ(saturated::Sub<float>(-big, -big), 0.0f);
503  EXPECT_EQ(saturated::Sub<float>(-max, -big), -big);
504  EXPECT_EQ(saturated::Sub<float>(-big, -max), big);
505  EXPECT_EQ(saturated::Sub<float>(-max, -max), 0.0f);
506  EXPECT_EQ(saturated::Sub<float>(-max, -inf), inf);
507  EXPECT_EQ(saturated::Sub<float>(-inf, -max), -inf);
508  EXPECT_TRUE(std::isnan(saturated::Sub<float>(-inf, -inf)));
509 
510  EXPECT_EQ(saturated::Sub<float>(big, -big), max);
511  EXPECT_EQ(saturated::Sub<float>(max, -big), inf);
512  EXPECT_EQ(saturated::Sub<float>(big, -max), inf);
513  EXPECT_EQ(saturated::Sub<float>(max, -max), inf);
514  EXPECT_EQ(saturated::Sub<float>(max, -inf), inf);
515  EXPECT_EQ(saturated::Sub<float>(inf, -max), inf);
516  EXPECT_EQ(saturated::Sub<float>(inf, -inf), inf);
517 
518  EXPECT_EQ(saturated::Sub<float>(-big, big), -max);
519  EXPECT_EQ(saturated::Sub<float>(-max, big), -inf);
520  EXPECT_EQ(saturated::Sub<float>(-big, max), -inf);
521  EXPECT_EQ(saturated::Sub<float>(-max, max), -inf);
522  EXPECT_EQ(saturated::Sub<float>(-max, inf), -inf);
523  EXPECT_EQ(saturated::Sub<float>(-inf, max), -inf);
524  EXPECT_EQ(saturated::Sub<float>(-inf, inf), -inf);
525  }
526  {
527  const double inf = std::numeric_limits<double>::infinity();
528  const double max = std::numeric_limits<double>::max();
529  const double big = max * 0.5f;
530 
531  EXPECT_EQ(saturated::Sub<double>(big, big), 0.0f);
532  EXPECT_EQ(saturated::Sub<double>(max, big), big);
533  EXPECT_EQ(saturated::Sub<double>(big, max), -big);
534  EXPECT_EQ(saturated::Sub<double>(max, max), 0.0f);
535  EXPECT_EQ(saturated::Sub<double>(max, inf), -inf);
536  EXPECT_EQ(saturated::Sub<double>(inf, max), inf);
537  EXPECT_TRUE(std::isnan(saturated::Sub<double>(inf, inf)));
538 
539  EXPECT_EQ(saturated::Sub<double>(-big, -big), 0.0f);
540  EXPECT_EQ(saturated::Sub<double>(-max, -big), -big);
541  EXPECT_EQ(saturated::Sub<double>(-big, -max), big);
542  EXPECT_EQ(saturated::Sub<double>(-max, -max), 0.0f);
543  EXPECT_EQ(saturated::Sub<double>(-max, -inf), inf);
544  EXPECT_EQ(saturated::Sub<double>(-inf, -max), -inf);
545  EXPECT_TRUE(std::isnan(saturated::Sub<double>(-inf, -inf)));
546 
547  EXPECT_EQ(saturated::Sub<double>(big, -big), max);
548  EXPECT_EQ(saturated::Sub<double>(max, -big), inf);
549  EXPECT_EQ(saturated::Sub<double>(big, -max), inf);
550  EXPECT_EQ(saturated::Sub<double>(max, -max), inf);
551  EXPECT_EQ(saturated::Sub<double>(max, -inf), inf);
552  EXPECT_EQ(saturated::Sub<double>(inf, -max), inf);
553  EXPECT_EQ(saturated::Sub<double>(inf, -inf), inf);
554 
555  EXPECT_EQ(saturated::Sub<double>(-big, big), -max);
556  EXPECT_EQ(saturated::Sub<double>(-max, big), -inf);
557  EXPECT_EQ(saturated::Sub<double>(-big, max), -inf);
558  EXPECT_EQ(saturated::Sub<double>(-max, max), -inf);
559  EXPECT_EQ(saturated::Sub<double>(-max, inf), -inf);
560  EXPECT_EQ(saturated::Sub<double>(-inf, max), -inf);
561  EXPECT_EQ(saturated::Sub<double>(-inf, inf), -inf);
562  }
563  {
564  const Scalar inf = std::numeric_limits<Scalar>::infinity();
565  const Scalar max = std::numeric_limits<Scalar>::max();
566  const Scalar big = max * 0.5f;
567 
568  EXPECT_EQ(saturated::Sub<Scalar>(big, big), 0.0f);
569  EXPECT_EQ(saturated::Sub<Scalar>(max, big), big);
570  EXPECT_EQ(saturated::Sub<Scalar>(big, max), -big);
571  EXPECT_EQ(saturated::Sub<Scalar>(max, max), 0.0f);
572  EXPECT_EQ(saturated::Sub<Scalar>(max, inf), -inf);
573  EXPECT_EQ(saturated::Sub<Scalar>(inf, max), inf);
574  EXPECT_TRUE(std::isnan(saturated::Sub<Scalar>(inf, inf)));
575 
576  EXPECT_EQ(saturated::Sub<Scalar>(-big, -big), 0.0f);
577  EXPECT_EQ(saturated::Sub<Scalar>(-max, -big), -big);
578  EXPECT_EQ(saturated::Sub<Scalar>(-big, -max), big);
579  EXPECT_EQ(saturated::Sub<Scalar>(-max, -max), 0.0f);
580  EXPECT_EQ(saturated::Sub<Scalar>(-max, -inf), inf);
581  EXPECT_EQ(saturated::Sub<Scalar>(-inf, -max), -inf);
582  EXPECT_TRUE(std::isnan(saturated::Sub<Scalar>(-inf, -inf)));
583 
584  EXPECT_EQ(saturated::Sub<Scalar>(big, -big), max);
585  EXPECT_EQ(saturated::Sub<Scalar>(max, -big), inf);
586  EXPECT_EQ(saturated::Sub<Scalar>(big, -max), inf);
587  EXPECT_EQ(saturated::Sub<Scalar>(max, -max), inf);
588  EXPECT_EQ(saturated::Sub<Scalar>(max, -inf), inf);
589  EXPECT_EQ(saturated::Sub<Scalar>(inf, -max), inf);
590  EXPECT_EQ(saturated::Sub<Scalar>(inf, -inf), inf);
591 
592  EXPECT_EQ(saturated::Sub<Scalar>(-big, big), -max);
593  EXPECT_EQ(saturated::Sub<Scalar>(-max, big), -inf);
594  EXPECT_EQ(saturated::Sub<Scalar>(-big, max), -inf);
595  EXPECT_EQ(saturated::Sub<Scalar>(-max, max), -inf);
596  EXPECT_EQ(saturated::Sub<Scalar>(-max, inf), -inf);
597  EXPECT_EQ(saturated::Sub<Scalar>(-inf, max), -inf);
598  EXPECT_EQ(saturated::Sub<Scalar>(-inf, inf), -inf);
599  }
600 }

◆ TEST() [330/370]

impeller::testing::TEST ( SaturatedMath  ,
ExplicitSubOfSignedInts   
)

Definition at line 364 of file saturated_math_unittests.cc.

364  {
365  {
366  EXPECT_EQ(saturated::Sub<int8_t>(0x79, -5), int8_t(0x7E));
367  EXPECT_EQ(saturated::Sub<int8_t>(0x7A, -5), int8_t(0x7F));
368  EXPECT_EQ(saturated::Sub<int8_t>(0x7B, -5), int8_t(0x7F));
369  }
370  {
371  EXPECT_EQ(saturated::Sub<int8_t>(0x86, 5), int8_t(0x81));
372  EXPECT_EQ(saturated::Sub<int8_t>(0x85, 5), int8_t(0x80));
373  EXPECT_EQ(saturated::Sub<int8_t>(0x84, 5), int8_t(0x80));
374  }
375  {
376  EXPECT_EQ(saturated::Sub<int16_t>(0x7FF9, -5), int16_t(0x7FFE));
377  EXPECT_EQ(saturated::Sub<int16_t>(0x7FFA, -5), int16_t(0x7FFF));
378  EXPECT_EQ(saturated::Sub<int16_t>(0x7FFB, -5), int16_t(0x7FFF));
379  }
380  {
381  EXPECT_EQ(saturated::Sub<int16_t>(0x8006, 5), int16_t(0x8001));
382  EXPECT_EQ(saturated::Sub<int16_t>(0x8005, 5), int16_t(0x8000));
383  EXPECT_EQ(saturated::Sub<int16_t>(0x8004, 5), int16_t(0x8000));
384  }
385  {
386  EXPECT_EQ(saturated::Sub<int32_t>(0x7FFFFFF9, -5), int32_t(0x7FFFFFFE));
387  EXPECT_EQ(saturated::Sub<int32_t>(0x7FFFFFFA, -5), int32_t(0x7FFFFFFF));
388  EXPECT_EQ(saturated::Sub<int32_t>(0x7FFFFFFB, -5), int32_t(0x7FFFFFFF));
389  }
390  {
391  EXPECT_EQ(saturated::Sub<int32_t>(0x80000006, 5), int32_t(0x80000001));
392  EXPECT_EQ(saturated::Sub<int32_t>(0x80000005, 5), int32_t(0x80000000));
393  EXPECT_EQ(saturated::Sub<int32_t>(0x80000004, 5), int32_t(0x80000000));
394  }
395  {
396  EXPECT_EQ(saturated::Sub<int64_t>(0x7FFFFFFFFFFFFFF9, -5),
397  int64_t(0x7FFFFFFFFFFFFFFE));
398  EXPECT_EQ(saturated::Sub<int64_t>(0x7FFFFFFFFFFFFFFA, -5),
399  int64_t(0x7FFFFFFFFFFFFFFF));
400  EXPECT_EQ(saturated::Sub<int64_t>(0x7FFFFFFFFFFFFFFB, -5),
401  int64_t(0x7FFFFFFFFFFFFFFF));
402  }
403  {
404  EXPECT_EQ(saturated::Sub<int64_t>(0x8000000000000006, 5),
405  int64_t(0x8000000000000001));
406  EXPECT_EQ(saturated::Sub<int64_t>(0x8000000000000005, 5),
407  int64_t(0x8000000000000000));
408  EXPECT_EQ(saturated::Sub<int64_t>(0x8000000000000004, 5),
409  int64_t(0x8000000000000000));
410  }
411 }

◆ TEST() [331/370]

impeller::testing::TEST ( SaturatedMath  ,
ImplicitAddOfFloatingPoint   
)

Definition at line 250 of file saturated_math_unittests.cc.

250  {
251  {
252  const float inf = std::numeric_limits<float>::infinity();
253  const float max = std::numeric_limits<float>::max();
254  const float big = max * 0.5f;
255 
256  EXPECT_EQ(saturated::Add(big, big), max);
257  EXPECT_EQ(saturated::Add(max, big), inf);
258  EXPECT_EQ(saturated::Add(big, max), inf);
259  EXPECT_EQ(saturated::Add(max, max), inf);
260  EXPECT_EQ(saturated::Add(max, inf), inf);
261  EXPECT_EQ(saturated::Add(inf, max), inf);
262  EXPECT_EQ(saturated::Add(inf, inf), inf);
263 
264  EXPECT_EQ(saturated::Add(-big, -big), -max);
265  EXPECT_EQ(saturated::Add(-max, -big), -inf);
266  EXPECT_EQ(saturated::Add(-big, -max), -inf);
267  EXPECT_EQ(saturated::Add(-max, -max), -inf);
268  EXPECT_EQ(saturated::Add(-max, -inf), -inf);
269  EXPECT_EQ(saturated::Add(-inf, -max), -inf);
270  EXPECT_EQ(saturated::Add(-inf, -inf), -inf);
271 
272  EXPECT_EQ(saturated::Add(big, -big), 0.0f);
273  EXPECT_EQ(saturated::Add(max, -big), big);
274  EXPECT_EQ(saturated::Add(big, -max), -big);
275  EXPECT_EQ(saturated::Add(max, -max), 0.0f);
276  EXPECT_EQ(saturated::Add(max, -inf), -inf);
277  EXPECT_EQ(saturated::Add(inf, -max), inf);
278  EXPECT_TRUE(std::isnan(saturated::Add(inf, -inf)));
279 
280  EXPECT_EQ(saturated::Add(-big, big), 0.0f);
281  EXPECT_EQ(saturated::Add(-max, big), -big);
282  EXPECT_EQ(saturated::Add(-big, max), big);
283  EXPECT_EQ(saturated::Add(-max, max), 0.0f);
284  EXPECT_EQ(saturated::Add(-max, inf), inf);
285  EXPECT_EQ(saturated::Add(-inf, max), -inf);
286  EXPECT_TRUE(std::isnan(saturated::Add(-inf, inf)));
287  }
288  {
289  const double inf = std::numeric_limits<double>::infinity();
290  const double max = std::numeric_limits<double>::max();
291  const double big = max * 0.5f;
292 
293  EXPECT_EQ(saturated::Add(big, big), max);
294  EXPECT_EQ(saturated::Add(max, big), inf);
295  EXPECT_EQ(saturated::Add(big, max), inf);
296  EXPECT_EQ(saturated::Add(max, max), inf);
297  EXPECT_EQ(saturated::Add(max, inf), inf);
298  EXPECT_EQ(saturated::Add(inf, max), inf);
299  EXPECT_EQ(saturated::Add(inf, inf), inf);
300 
301  EXPECT_EQ(saturated::Add(-big, -big), -max);
302  EXPECT_EQ(saturated::Add(-max, -big), -inf);
303  EXPECT_EQ(saturated::Add(-big, -max), -inf);
304  EXPECT_EQ(saturated::Add(-max, -max), -inf);
305  EXPECT_EQ(saturated::Add(-max, -inf), -inf);
306  EXPECT_EQ(saturated::Add(-inf, -max), -inf);
307  EXPECT_EQ(saturated::Add(-inf, -inf), -inf);
308 
309  EXPECT_EQ(saturated::Add(big, -big), 0.0f);
310  EXPECT_EQ(saturated::Add(max, -big), big);
311  EXPECT_EQ(saturated::Add(big, -max), -big);
312  EXPECT_EQ(saturated::Add(max, -max), 0.0f);
313  EXPECT_EQ(saturated::Add(max, -inf), -inf);
314  EXPECT_EQ(saturated::Add(inf, -max), inf);
315  EXPECT_TRUE(std::isnan(saturated::Add(inf, -inf)));
316 
317  EXPECT_EQ(saturated::Add(-big, big), 0.0f);
318  EXPECT_EQ(saturated::Add(-max, big), -big);
319  EXPECT_EQ(saturated::Add(-big, max), big);
320  EXPECT_EQ(saturated::Add(-max, max), 0.0f);
321  EXPECT_EQ(saturated::Add(-max, inf), inf);
322  EXPECT_EQ(saturated::Add(-inf, max), -inf);
323  EXPECT_TRUE(std::isnan(saturated::Add(-inf, inf)));
324  }
325  {
326  const Scalar inf = std::numeric_limits<Scalar>::infinity();
327  const Scalar max = std::numeric_limits<Scalar>::max();
328  const Scalar big = max * 0.5f;
329 
330  EXPECT_EQ(saturated::Add(big, big), max);
331  EXPECT_EQ(saturated::Add(max, big), inf);
332  EXPECT_EQ(saturated::Add(big, max), inf);
333  EXPECT_EQ(saturated::Add(max, max), inf);
334  EXPECT_EQ(saturated::Add(max, inf), inf);
335  EXPECT_EQ(saturated::Add(inf, max), inf);
336  EXPECT_EQ(saturated::Add(inf, inf), inf);
337 
338  EXPECT_EQ(saturated::Add(-big, -big), -max);
339  EXPECT_EQ(saturated::Add(-max, -big), -inf);
340  EXPECT_EQ(saturated::Add(-big, -max), -inf);
341  EXPECT_EQ(saturated::Add(-max, -max), -inf);
342  EXPECT_EQ(saturated::Add(-max, -inf), -inf);
343  EXPECT_EQ(saturated::Add(-inf, -max), -inf);
344  EXPECT_EQ(saturated::Add(-inf, -inf), -inf);
345 
346  EXPECT_EQ(saturated::Add(big, -big), 0.0f);
347  EXPECT_EQ(saturated::Add(max, -big), big);
348  EXPECT_EQ(saturated::Add(big, -max), -big);
349  EXPECT_EQ(saturated::Add(max, -max), 0.0f);
350  EXPECT_EQ(saturated::Add(max, -inf), -inf);
351  EXPECT_EQ(saturated::Add(inf, -max), inf);
352  EXPECT_TRUE(std::isnan(saturated::Add(inf, -inf)));
353 
354  EXPECT_EQ(saturated::Add(-big, big), 0.0f);
355  EXPECT_EQ(saturated::Add(-max, big), -big);
356  EXPECT_EQ(saturated::Add(-big, max), big);
357  EXPECT_EQ(saturated::Add(-max, max), 0.0f);
358  EXPECT_EQ(saturated::Add(-max, inf), inf);
359  EXPECT_EQ(saturated::Add(-inf, max), -inf);
360  EXPECT_TRUE(std::isnan(saturated::Add(-inf, inf)));
361  }
362 }

◆ TEST() [332/370]

impeller::testing::TEST ( SaturatedMath  ,
ImplicitAddOfSignedInts   
)

Definition at line 61 of file saturated_math_unittests.cc.

61  {
62  {
63  int8_t a = 0x79;
64  int8_t b = 5;
65  EXPECT_EQ(saturated::Add(a, b), int8_t(0x7E));
66  a = 0x7A;
67  EXPECT_EQ(saturated::Add(a, b), int8_t(0x7F));
68  a = 0x7B;
69  EXPECT_EQ(saturated::Add(a, b), int8_t(0x7F));
70  }
71  {
72  int8_t a = 0x86;
73  int8_t b = -5;
74  EXPECT_EQ(saturated::Add(a, b), int8_t(0x81));
75  a = 0x85;
76  EXPECT_EQ(saturated::Add(a, b), int8_t(0x80));
77  a = 0x84;
78  EXPECT_EQ(saturated::Add(a, b), int8_t(0x80));
79  }
80  {
81  int16_t a = 0x7FF9;
82  int16_t b = 5;
83  EXPECT_EQ(saturated::Add(a, b), int16_t(0x7FFE));
84  a = 0x7FFA;
85  EXPECT_EQ(saturated::Add(a, b), int16_t(0x7FFF));
86  a = 0x7FFB;
87  EXPECT_EQ(saturated::Add(a, b), int16_t(0x7FFF));
88  }
89  {
90  int16_t a = 0x8006;
91  int16_t b = -5;
92  EXPECT_EQ(saturated::Add(a, b), int16_t(0x8001));
93  a = 0x8005;
94  EXPECT_EQ(saturated::Add(a, b), int16_t(0x8000));
95  a = 0x8004;
96  EXPECT_EQ(saturated::Add(a, b), int16_t(0x8000));
97  }
98  {
99  int32_t a = 0x7FFFFFF9;
100  int32_t b = 5;
101  EXPECT_EQ(saturated::Add(a, b), int32_t(0x7FFFFFFE));
102  a = 0x7FFFFFFA;
103  EXPECT_EQ(saturated::Add(a, b), int32_t(0x7FFFFFFF));
104  a = 0x7FFFFFFB;
105  EXPECT_EQ(saturated::Add(a, b), int32_t(0x7FFFFFFF));
106  }
107  {
108  int32_t a = 0x80000006;
109  int32_t b = -5;
110  EXPECT_EQ(saturated::Add(a, b), int32_t(0x80000001));
111  a = 0x80000005;
112  EXPECT_EQ(saturated::Add(a, b), int32_t(0x80000000));
113  a = 0x80000004;
114  EXPECT_EQ(saturated::Add(a, b), int32_t(0x80000000));
115  }
116  {
117  int64_t a = 0x7FFFFFFFFFFFFFF9;
118  int64_t b = 5;
119  EXPECT_EQ(saturated::Add(a, b), int64_t(0x7FFFFFFFFFFFFFFE));
120  a = 0x7FFFFFFFFFFFFFFA;
121  EXPECT_EQ(saturated::Add(a, b), int64_t(0x7FFFFFFFFFFFFFFF));
122  a = 0x7FFFFFFFFFFFFFFB;
123  EXPECT_EQ(saturated::Add(a, b), int64_t(0x7FFFFFFFFFFFFFFF));
124  }
125  {
126  int64_t a = 0x8000000000000006;
127  int64_t b = -5;
128  EXPECT_EQ(saturated::Add(a, b), int64_t(0x8000000000000001));
129  a = 0x8000000000000005;
130  EXPECT_EQ(saturated::Add(a, b), int64_t(0x8000000000000000));
131  a = 0x8000000000000004;
132  EXPECT_EQ(saturated::Add(a, b), int64_t(0x8000000000000000));
133  }
134 }

References impeller::saturated::b.

◆ TEST() [333/370]

impeller::testing::TEST ( SaturatedMath  ,
ImplicitAverageScalarOfFloatingPoint   
)

Definition at line 903 of file saturated_math_unittests.cc.

903  {
904  // All return values are Scalar regardless of the operand types
905  // so these constants are used as the expected answers.
906  const Scalar s_inf = std::numeric_limits<Scalar>::infinity();
907  const Scalar s_max = std::numeric_limits<Scalar>::max();
908  const Scalar s_big = s_max * 0.5f;
909 
910  {
911  const float inf = std::numeric_limits<float>::infinity();
912  const float max = std::numeric_limits<float>::max();
913  const float big = max * 0.5f;
914 
915  EXPECT_EQ(saturated::AverageScalar(big, big), s_big);
916  EXPECT_EQ(saturated::AverageScalar(max, max), s_max);
917  EXPECT_EQ(saturated::AverageScalar(big, -big), 0.0f);
918  EXPECT_EQ(saturated::AverageScalar(max, -max), 0.0f);
919  EXPECT_EQ(saturated::AverageScalar(-big, big), 0.0f);
920  EXPECT_EQ(saturated::AverageScalar(-max, max), 0.0f);
921  EXPECT_EQ(saturated::AverageScalar(-big, -big), -s_big);
922  EXPECT_EQ(saturated::AverageScalar(-max, -max), -s_max);
923 
924  EXPECT_EQ(saturated::AverageScalar(inf, inf), s_inf);
925  EXPECT_EQ(saturated::AverageScalar(-inf, -inf), -s_inf);
926  EXPECT_TRUE(std::isnan(saturated::AverageScalar(-inf, inf)));
927  EXPECT_TRUE(std::isnan(saturated::AverageScalar(inf, -inf)));
928  }
929  {
930  const double inf = std::numeric_limits<double>::infinity();
931  const double max = std::numeric_limits<double>::max();
932  const double big = max * 0.5;
933 
934  // The s_constants converted to double. We should get finite results
935  // from finding the averages of these values, but we'll get a lot of
936  // overflow to infinity when testing the large double constants.
937  const double d_s_max = s_max;
938  const double d_s_big = s_big;
939  EXPECT_EQ(saturated::AverageScalar(d_s_big, d_s_big), s_big);
940  EXPECT_EQ(saturated::AverageScalar(d_s_max, d_s_max), s_max);
941  EXPECT_EQ(saturated::AverageScalar(-d_s_big, -d_s_big), -s_big);
942  EXPECT_EQ(saturated::AverageScalar(-d_s_max, -d_s_max), -s_max);
943 
944  // And now testing continues with the double constants which
945  // mostly overflow
946  EXPECT_EQ(saturated::AverageScalar(big, big), s_inf);
947  EXPECT_EQ(saturated::AverageScalar(max, max), s_inf);
948  EXPECT_EQ(saturated::AverageScalar(big, -big), 0.0f);
949  EXPECT_EQ(saturated::AverageScalar(max, -max), 0.0f);
950  EXPECT_EQ(saturated::AverageScalar(-big, big), 0.0f);
951  EXPECT_EQ(saturated::AverageScalar(-max, max), 0.0f);
952  EXPECT_EQ(saturated::AverageScalar(-big, -big), -s_inf);
953  EXPECT_EQ(saturated::AverageScalar(-max, -max), -s_inf);
954 
955  EXPECT_EQ(saturated::AverageScalar(inf, inf), s_inf);
956  EXPECT_EQ(saturated::AverageScalar(-inf, -inf), -s_inf);
957  EXPECT_TRUE(std::isnan(saturated::AverageScalar(-inf, inf)));
958  EXPECT_TRUE(std::isnan(saturated::AverageScalar(inf, -inf)));
959  }
960  {
961  const Scalar inf = std::numeric_limits<Scalar>::infinity();
962  const Scalar max = std::numeric_limits<Scalar>::max();
963  const Scalar big = max * 0.5f;
964 
965  EXPECT_EQ(saturated::AverageScalar(big, big), s_big);
966  EXPECT_EQ(saturated::AverageScalar(max, max), s_max);
967  EXPECT_EQ(saturated::AverageScalar(big, -big), 0.0f);
968  EXPECT_EQ(saturated::AverageScalar(max, -max), 0.0f);
969  EXPECT_EQ(saturated::AverageScalar(-big, big), 0.0f);
970  EXPECT_EQ(saturated::AverageScalar(-max, max), 0.0f);
971  EXPECT_EQ(saturated::AverageScalar(-big, -big), -s_big);
972  EXPECT_EQ(saturated::AverageScalar(-max, -max), -s_max);
973 
974  EXPECT_EQ(saturated::AverageScalar(inf, inf), s_inf);
975  EXPECT_EQ(saturated::AverageScalar(-inf, -inf), -s_inf);
976  EXPECT_TRUE(std::isnan(saturated::AverageScalar(-inf, s_inf)));
977  EXPECT_TRUE(std::isnan(saturated::AverageScalar(inf, -s_inf)));
978  }
979 }

◆ TEST() [334/370]

impeller::testing::TEST ( SaturatedMath  ,
ImplicitAverageScalarOfSignedInts   
)

Definition at line 763 of file saturated_math_unittests.cc.

763  {
764  // For each type try:
765  //
766  // - near the limits, averaging to 0
767  // - at the limits, averaging to 0 or 0.5 depending on precision
768  // - both large enough for the sum to overflow
769  // - both negative enough for the sum to underflow
770  {
771  int8_t a = 0x81;
772  int8_t b = 0x7f;
773  EXPECT_EQ(saturated::AverageScalar(a, b), -0.0f);
774  a = 0x80;
775  EXPECT_EQ(saturated::AverageScalar(a, b), -0.5f);
776  a = 0x70;
777  b = 0x75;
778  EXPECT_EQ(saturated::AverageScalar(a, b), 114.5f);
779  a = 0x85;
780  b = 0x8A;
781  EXPECT_EQ(saturated::AverageScalar(a, b), -120.5f);
782  }
783  {
784  int16_t a = 0x8001;
785  int16_t b = 0x7FFF;
786  EXPECT_EQ(saturated::AverageScalar(a, b), -0.0f);
787  a = 0x8000;
788  EXPECT_EQ(saturated::AverageScalar(a, b), -0.5f);
789  a = 0x7000;
790  b = 0x7005;
791  EXPECT_EQ(saturated::AverageScalar(a, b), 28674.5f);
792  a = 0x8005;
793  b = 0x800A;
794  EXPECT_EQ(saturated::AverageScalar(a, b), -32760.5f);
795  }
796  {
797  int32_t a = 0x80000001;
798  int32_t b = 0x7FFFFFFF;
799  EXPECT_EQ(saturated::AverageScalar(a, b), -0.0f);
800  a = 0x80000000;
801  EXPECT_EQ(saturated::AverageScalar(a, b), -0.5f);
802  a = 0x70000000;
803  b = 0x70000005;
804  EXPECT_EQ(saturated::AverageScalar(a, b), 1879048195.5f);
805  a = 0x80000005;
806  b = 0x8000000A;
807  EXPECT_EQ(saturated::AverageScalar(a, b), -2147483655.5f);
808  }
809  {
810  int64_t a = 0x8000000000000001;
811  int64_t b = 0x7FFFFFFFFFFFFFFF;
812  EXPECT_EQ(saturated::AverageScalar(a, b), 0.0f);
813  // 64-bit integers overflow the ability of a Scalar (float) to
814  // represent discrete integers and so the two numbers we are
815  // averaging here will look like the same number with different
816  // signs and the answer will be "0"
817  a = 0x8000000000000000;
818  EXPECT_EQ(saturated::AverageScalar<int64_t>(a, b), 0.0f);
819  a = 0x7000000000000000;
820  b = 0x7000000000000005;
821  EXPECT_NEAR(saturated::AverageScalar<int64_t>(a, b), 8.0704505e+18, 1e18);
822  a = 0x8000000000000005;
823  b = 0x800000000000000A;
824  EXPECT_NEAR(saturated::AverageScalar<int64_t>(a, b), -9.223372e+18, 1e18);
825  }
826 }

References impeller::saturated::b.

◆ TEST() [335/370]

impeller::testing::TEST ( SaturatedMath  ,
ImplicitSubOfFloatingPoint   
)

Definition at line 602 of file saturated_math_unittests.cc.

602  {
603  {
604  const float inf = std::numeric_limits<float>::infinity();
605  const float max = std::numeric_limits<float>::max();
606  const float big = max * 0.5f;
607 
608  EXPECT_EQ(saturated::Sub(big, big), 0.0f);
609  EXPECT_EQ(saturated::Sub(max, big), big);
610  EXPECT_EQ(saturated::Sub(big, max), -big);
611  EXPECT_EQ(saturated::Sub(max, max), 0.0f);
612  EXPECT_EQ(saturated::Sub(max, inf), -inf);
613  EXPECT_EQ(saturated::Sub(inf, max), inf);
614  EXPECT_TRUE(std::isnan(saturated::Sub(inf, inf)));
615 
616  EXPECT_EQ(saturated::Sub(-big, -big), 0.0f);
617  EXPECT_EQ(saturated::Sub(-max, -big), -big);
618  EXPECT_EQ(saturated::Sub(-big, -max), big);
619  EXPECT_EQ(saturated::Sub(-max, -max), 0.0f);
620  EXPECT_EQ(saturated::Sub(-max, -inf), inf);
621  EXPECT_EQ(saturated::Sub(-inf, -max), -inf);
622  EXPECT_TRUE(std::isnan(saturated::Sub(-inf, -inf)));
623 
624  EXPECT_EQ(saturated::Sub(big, -big), max);
625  EXPECT_EQ(saturated::Sub(max, -big), inf);
626  EXPECT_EQ(saturated::Sub(big, -max), inf);
627  EXPECT_EQ(saturated::Sub(max, -max), inf);
628  EXPECT_EQ(saturated::Sub(max, -inf), inf);
629  EXPECT_EQ(saturated::Sub(inf, -max), inf);
630  EXPECT_EQ(saturated::Sub(inf, -inf), inf);
631 
632  EXPECT_EQ(saturated::Sub(-big, big), -max);
633  EXPECT_EQ(saturated::Sub(-max, big), -inf);
634  EXPECT_EQ(saturated::Sub(-big, max), -inf);
635  EXPECT_EQ(saturated::Sub(-max, max), -inf);
636  EXPECT_EQ(saturated::Sub(-max, inf), -inf);
637  EXPECT_EQ(saturated::Sub(-inf, max), -inf);
638  EXPECT_EQ(saturated::Sub(-inf, inf), -inf);
639  }
640  {
641  const double inf = std::numeric_limits<double>::infinity();
642  const double max = std::numeric_limits<double>::max();
643  const double big = max * 0.5f;
644 
645  EXPECT_EQ(saturated::Sub(big, big), 0.0f);
646  EXPECT_EQ(saturated::Sub(max, big), big);
647  EXPECT_EQ(saturated::Sub(big, max), -big);
648  EXPECT_EQ(saturated::Sub(max, max), 0.0f);
649  EXPECT_EQ(saturated::Sub(max, inf), -inf);
650  EXPECT_EQ(saturated::Sub(inf, max), inf);
651  EXPECT_TRUE(std::isnan(saturated::Sub(inf, inf)));
652 
653  EXPECT_EQ(saturated::Sub(-big, -big), 0.0f);
654  EXPECT_EQ(saturated::Sub(-max, -big), -big);
655  EXPECT_EQ(saturated::Sub(-big, -max), big);
656  EXPECT_EQ(saturated::Sub(-max, -max), 0.0f);
657  EXPECT_EQ(saturated::Sub(-max, -inf), inf);
658  EXPECT_EQ(saturated::Sub(-inf, -max), -inf);
659  EXPECT_TRUE(std::isnan(saturated::Sub(-inf, -inf)));
660 
661  EXPECT_EQ(saturated::Sub(big, -big), max);
662  EXPECT_EQ(saturated::Sub(max, -big), inf);
663  EXPECT_EQ(saturated::Sub(big, -max), inf);
664  EXPECT_EQ(saturated::Sub(max, -max), inf);
665  EXPECT_EQ(saturated::Sub(max, -inf), inf);
666  EXPECT_EQ(saturated::Sub(inf, -max), inf);
667  EXPECT_EQ(saturated::Sub(inf, -inf), inf);
668 
669  EXPECT_EQ(saturated::Sub(-big, big), -max);
670  EXPECT_EQ(saturated::Sub(-max, big), -inf);
671  EXPECT_EQ(saturated::Sub(-big, max), -inf);
672  EXPECT_EQ(saturated::Sub(-max, max), -inf);
673  EXPECT_EQ(saturated::Sub(-max, inf), -inf);
674  EXPECT_EQ(saturated::Sub(-inf, max), -inf);
675  EXPECT_EQ(saturated::Sub(-inf, inf), -inf);
676  }
677  {
678  const Scalar inf = std::numeric_limits<Scalar>::infinity();
679  const Scalar max = std::numeric_limits<Scalar>::max();
680  const Scalar big = max * 0.5f;
681 
682  EXPECT_EQ(saturated::Sub(big, big), 0.0f);
683  EXPECT_EQ(saturated::Sub(max, big), big);
684  EXPECT_EQ(saturated::Sub(big, max), -big);
685  EXPECT_EQ(saturated::Sub(max, max), 0.0f);
686  EXPECT_EQ(saturated::Sub(max, inf), -inf);
687  EXPECT_EQ(saturated::Sub(inf, max), inf);
688  EXPECT_TRUE(std::isnan(saturated::Sub(inf, inf)));
689 
690  EXPECT_EQ(saturated::Sub(-big, -big), 0.0f);
691  EXPECT_EQ(saturated::Sub(-max, -big), -big);
692  EXPECT_EQ(saturated::Sub(-big, -max), big);
693  EXPECT_EQ(saturated::Sub(-max, -max), 0.0f);
694  EXPECT_EQ(saturated::Sub(-max, -inf), inf);
695  EXPECT_EQ(saturated::Sub(-inf, -max), -inf);
696  EXPECT_TRUE(std::isnan(saturated::Sub(-inf, -inf)));
697 
698  EXPECT_EQ(saturated::Sub(big, -big), max);
699  EXPECT_EQ(saturated::Sub(max, -big), inf);
700  EXPECT_EQ(saturated::Sub(big, -max), inf);
701  EXPECT_EQ(saturated::Sub(max, -max), inf);
702  EXPECT_EQ(saturated::Sub(max, -inf), inf);
703  EXPECT_EQ(saturated::Sub(inf, -max), inf);
704  EXPECT_EQ(saturated::Sub(inf, -inf), inf);
705 
706  EXPECT_EQ(saturated::Sub(-big, big), -max);
707  EXPECT_EQ(saturated::Sub(-max, big), -inf);
708  EXPECT_EQ(saturated::Sub(-big, max), -inf);
709  EXPECT_EQ(saturated::Sub(-max, max), -inf);
710  EXPECT_EQ(saturated::Sub(-max, inf), -inf);
711  EXPECT_EQ(saturated::Sub(-inf, max), -inf);
712  EXPECT_EQ(saturated::Sub(-inf, inf), -inf);
713  }
714 }

◆ TEST() [336/370]

impeller::testing::TEST ( SaturatedMath  ,
ImplicitSubOfSignedInts   
)

Definition at line 413 of file saturated_math_unittests.cc.

413  {
414  {
415  int8_t a = 0x79;
416  int8_t b = -5;
417  EXPECT_EQ(saturated::Sub(a, b), int8_t(0x7E));
418  a = 0x7A;
419  EXPECT_EQ(saturated::Sub(a, b), int8_t(0x7F));
420  a = 0x7B;
421  EXPECT_EQ(saturated::Sub(a, b), int8_t(0x7F));
422  }
423  {
424  int8_t a = 0x86;
425  int8_t b = 5;
426  EXPECT_EQ(saturated::Sub(a, b), int8_t(0x81));
427  a = 0x85;
428  EXPECT_EQ(saturated::Sub(a, b), int8_t(0x80));
429  a = 0x84;
430  EXPECT_EQ(saturated::Sub(a, b), int8_t(0x80));
431  }
432  {
433  int16_t a = 0x7FF9;
434  int16_t b = -5;
435  EXPECT_EQ(saturated::Sub(a, b), int16_t(0x7FFE));
436  a = 0x7FFA;
437  EXPECT_EQ(saturated::Sub(a, b), int16_t(0x7FFF));
438  a = 0x7FFB;
439  EXPECT_EQ(saturated::Sub(a, b), int16_t(0x7FFF));
440  }
441  {
442  int16_t a = 0x8006;
443  int16_t b = 5;
444  EXPECT_EQ(saturated::Sub(a, b), int16_t(0x8001));
445  a = 0x8005;
446  EXPECT_EQ(saturated::Sub(a, b), int16_t(0x8000));
447  a = 0x8004;
448  EXPECT_EQ(saturated::Sub(a, b), int16_t(0x8000));
449  }
450  {
451  int32_t a = 0x7FFFFFF9;
452  int32_t b = -5;
453  EXPECT_EQ(saturated::Sub(a, b), int32_t(0x7FFFFFFE));
454  a = 0x7FFFFFFA;
455  EXPECT_EQ(saturated::Sub(a, b), int32_t(0x7FFFFFFF));
456  a = 0x7FFFFFFB;
457  EXPECT_EQ(saturated::Sub(a, b), int32_t(0x7FFFFFFF));
458  }
459  {
460  int32_t a = 0x80000006;
461  int32_t b = 5;
462  EXPECT_EQ(saturated::Sub(a, b), int32_t(0x80000001));
463  a = 0x80000005;
464  EXPECT_EQ(saturated::Sub(a, b), int32_t(0x80000000));
465  a = 0x80000004;
466  EXPECT_EQ(saturated::Sub(a, b), int32_t(0x80000000));
467  }
468  {
469  int64_t a = 0x7FFFFFFFFFFFFFF9;
470  int64_t b = -5;
471  EXPECT_EQ(saturated::Sub(a, b), int64_t(0x7FFFFFFFFFFFFFFE));
472  a = 0x7FFFFFFFFFFFFFFA;
473  EXPECT_EQ(saturated::Sub(a, b), int64_t(0x7FFFFFFFFFFFFFFF));
474  a = 0x7FFFFFFFFFFFFFFB;
475  EXPECT_EQ(saturated::Sub(a, b), int64_t(0x7FFFFFFFFFFFFFFF));
476  }
477  {
478  int64_t a = 0x8000000000000006;
479  int64_t b = 5;
480  EXPECT_EQ(saturated::Sub(a, b), int64_t(0x8000000000000001));
481  a = 0x8000000000000005;
482  EXPECT_EQ(saturated::Sub(a, b), int64_t(0x8000000000000000));
483  a = 0x8000000000000004;
484  EXPECT_EQ(saturated::Sub(a, b), int64_t(0x8000000000000000));
485  }
486 }

References impeller::saturated::b.

◆ TEST() [337/370]

impeller::testing::TEST ( ShaderArchiveTest  ,
ArchiveAndMultiArchiveHaveDifferentIdentifiers   
)

Definition at line 84 of file shader_archive_unittests.cc.

84  {
85  // The unarchiving process depends on these identifiers to check to see if its
86  // a standalone archive or a multi-archive. Things will get nutty if these are
87  // ever the same.
88  auto archive_id = fb::ShaderArchiveIdentifier();
89  auto multi_archive_id = fb::MultiArchShaderArchiveIdentifier();
90  ASSERT_EQ(std::strlen(archive_id), std::strlen(multi_archive_id));
91  ASSERT_NE(std::strncmp(archive_id, multi_archive_id, std::strlen(archive_id)),
92  0);
93 }

◆ TEST() [338/370]

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

Definition at line 33 of file shader_archive_unittests.cc.

33  {
34  ShaderArchiveWriter writer;
35  ASSERT_TRUE(writer.AddShader(ArchiveShaderType::kVertex, "Hello",
36  CreateMappingFromString("World")));
37  ASSERT_TRUE(writer.AddShader(ArchiveShaderType::kFragment, "Foo",
38  CreateMappingFromString("Bar")));
39  ASSERT_TRUE(writer.AddShader(ArchiveShaderType::kVertex, "Baz",
40  CreateMappingFromString("Bang")));
41  ASSERT_TRUE(writer.AddShader(ArchiveShaderType::kVertex, "Ping",
42  CreateMappingFromString("Pong")));
43  ASSERT_TRUE(writer.AddShader(ArchiveShaderType::kFragment, "Pang",
44  CreateMappingFromString("World")));
45 
46  auto mapping = writer.CreateMapping();
47  ASSERT_NE(mapping, nullptr);
48 
49  MultiArchShaderArchiveWriter multi_writer;
50 
51  ASSERT_TRUE(multi_writer.RegisterShaderArchive(
52  ArchiveRenderingBackend::kOpenGLES, mapping));
53 
54  {
55  ScopedValidationDisable no_val;
56  // Can't add the same backend again.
57  ASSERT_FALSE(multi_writer.RegisterShaderArchive(
58  ArchiveRenderingBackend::kOpenGLES, mapping));
59  }
60 
61  auto multi_mapping = multi_writer.CreateMapping();
62  ASSERT_TRUE(multi_mapping);
63 
64  {
65  ScopedValidationDisable no_val;
66  auto no_library = MultiArchShaderArchive::CreateArchiveFromMapping(
67  multi_mapping, ArchiveRenderingBackend::kVulkan);
68  ASSERT_EQ(no_library, nullptr);
69  }
70 
71  auto library = MultiArchShaderArchive::CreateArchiveFromMapping(
72  multi_mapping, ArchiveRenderingBackend::kOpenGLES);
73  ASSERT_EQ(library->GetShaderCount(), 5u);
74 
75  // Wrong type.
76  ASSERT_EQ(library->GetMapping(ArchiveShaderType::kFragment, "Hello"),
77  nullptr);
78 
79  auto hello_vtx = library->GetMapping(ArchiveShaderType::kVertex, "Hello");
80  ASSERT_NE(hello_vtx, nullptr);
81  ASSERT_EQ(CreateStringFromMapping(*hello_vtx), "World");
82 }

References impeller::ShaderArchiveWriter::AddShader(), impeller::MultiArchShaderArchive::CreateArchiveFromMapping(), impeller::MultiArchShaderArchiveWriter::CreateMapping(), impeller::ShaderArchiveWriter::CreateMapping(), CreateMappingFromString(), CreateStringFromMapping(), impeller::kFragment, impeller::kOpenGLES, impeller::kVertex, impeller::kVulkan, and impeller::MultiArchShaderArchiveWriter::RegisterShaderArchive().

◆ TEST() [339/370]

impeller::testing::TEST ( SizeTest  ,
ISizeIsEmpty   
)

Definition at line 36 of file size_unittests.cc.

36  {
37  // Non-empty
38  EXPECT_FALSE(ISize(10, 7).IsEmpty());
39 
40  // Empty both width and height both 0 or negative, in all combinations
41  EXPECT_TRUE(ISize(0, 0).IsEmpty());
42  EXPECT_TRUE(ISize(-1, -1).IsEmpty());
43  EXPECT_TRUE(ISize(-1, 0).IsEmpty());
44  EXPECT_TRUE(ISize(0, -1).IsEmpty());
45 
46  // Empty for 0 or negative width or height (but not both at the same time)
47  EXPECT_TRUE(ISize(10, 0).IsEmpty());
48  EXPECT_TRUE(ISize(10, -1).IsEmpty());
49  EXPECT_TRUE(ISize(0, 7).IsEmpty());
50  EXPECT_TRUE(ISize(-1, 7).IsEmpty());
51 }

◆ TEST() [340/370]

impeller::testing::TEST ( SizeTest  ,
IsSquare   
)

Definition at line 53 of file size_unittests.cc.

53  {
54  EXPECT_TRUE(Size(20, 20).IsSquare());
55  EXPECT_FALSE(Size(20, 19).IsSquare());
56  EXPECT_FALSE(Size(19, 20).IsSquare());
57 
58  EXPECT_TRUE(ISize(20, 20).IsSquare());
59  EXPECT_FALSE(ISize(20, 19).IsSquare());
60  EXPECT_FALSE(ISize(19, 20).IsSquare());
61 }

◆ TEST() [341/370]

impeller::testing::TEST ( SizeTest  ,
MaxDimension   
)

Definition at line 63 of file size_unittests.cc.

63  {
64  EXPECT_EQ(Size(20, 20).MaxDimension(), 20);
65  EXPECT_EQ(Size(20, 19).MaxDimension(), 20);
66  EXPECT_EQ(Size(19, 20).MaxDimension(), 20);
67  EXPECT_EQ(Size(20, 21).MaxDimension(), 21);
68  EXPECT_EQ(Size(21, 20).MaxDimension(), 21);
69 
70  EXPECT_EQ(ISize(20, 20).MaxDimension(), 20);
71  EXPECT_EQ(ISize(20, 19).MaxDimension(), 20);
72  EXPECT_EQ(ISize(19, 20).MaxDimension(), 20);
73  EXPECT_EQ(ISize(20, 21).MaxDimension(), 21);
74  EXPECT_EQ(ISize(21, 20).MaxDimension(), 21);
75 }

◆ TEST() [342/370]

impeller::testing::TEST ( SizeTest  ,
NegationOperator   
)

Definition at line 77 of file size_unittests.cc.

77  {
78  EXPECT_EQ(-Size(10, 20), Size(-10, -20));
79  EXPECT_EQ(-Size(-10, 20), Size(10, -20));
80  EXPECT_EQ(-Size(10, -20), Size(-10, 20));
81  EXPECT_EQ(-Size(-10, -20), Size(10, 20));
82 }

◆ TEST() [343/370]

impeller::testing::TEST ( SizeTest  ,
SizeIsEmpty   
)

Definition at line 12 of file size_unittests.cc.

12  {
13  auto nan = std::numeric_limits<Scalar>::quiet_NaN();
14 
15  // Non-empty
16  EXPECT_FALSE(Size(10.5, 7.2).IsEmpty());
17 
18  // Empty both width and height both 0 or negative, in all combinations
19  EXPECT_TRUE(Size(0.0, 0.0).IsEmpty());
20  EXPECT_TRUE(Size(-1.0, -1.0).IsEmpty());
21  EXPECT_TRUE(Size(-1.0, 0.0).IsEmpty());
22  EXPECT_TRUE(Size(0.0, -1.0).IsEmpty());
23 
24  // Empty for 0 or negative width or height (but not both at the same time)
25  EXPECT_TRUE(Size(10.5, 0.0).IsEmpty());
26  EXPECT_TRUE(Size(10.5, -1.0).IsEmpty());
27  EXPECT_TRUE(Size(0.0, 7.2).IsEmpty());
28  EXPECT_TRUE(Size(-1.0, 7.2).IsEmpty());
29 
30  // Empty for NaN in width or height or both
31  EXPECT_TRUE(Size(10.5, nan).IsEmpty());
32  EXPECT_TRUE(Size(nan, 7.2).IsEmpty());
33  EXPECT_TRUE(Size(nan, nan).IsEmpty());
34 }

◆ TEST() [344/370]

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

Definition at line 150 of file skia_conversions_unittests.cc.

150  {
151  std::vector<flutter::DlColor> colors = {
152  flutter::DlColor::kBlue(), flutter::DlColor::kGreen(),
153  flutter::DlColor::kGreen(), flutter::DlColor::kRed()};
154  std::vector<float> stops = {0.0, 0.5, 0.4, 1.0};
155  const auto gradient =
156  flutter::DlColorSource::MakeLinear(SkPoint::Make(0, 0), //
157  SkPoint::Make(1.0, 1.0), //
158  4, //
159  colors.data(), //
160  stops.data(), //
161  flutter::DlTileMode::kClamp, //
162  nullptr //
163  );
164 
165  std::vector<Color> converted_colors;
166  std::vector<Scalar> converted_stops;
167  skia_conversions::ConvertStops(gradient.get(), converted_colors,
168  converted_stops);
169 
170  // Value is clamped to 0.5
171  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[0], 0.0f));
172  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[1], 0.5f));
173  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[2], 0.5f));
174  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[3], 1.0f));
175 }

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

◆ TEST() [345/370]

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

Definition at line 72 of file skia_conversions_unittests.cc.

72  {
73  std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
74  flutter::DlColor::kRed()};
75  std::vector<float> stops = {0.5, 1.0};
76  const auto gradient =
77  flutter::DlColorSource::MakeLinear(SkPoint::Make(0, 0), //
78  SkPoint::Make(1.0, 1.0), //
79  2, //
80  colors.data(), //
81  stops.data(), //
82  flutter::DlTileMode::kClamp, //
83  nullptr //
84  );
85 
86  std::vector<Color> converted_colors;
87  std::vector<Scalar> converted_stops;
88  skia_conversions::ConvertStops(gradient.get(), converted_colors,
89  converted_stops);
90 
91  // First color is inserted as blue.
92  ASSERT_TRUE(ScalarNearlyEqual(converted_colors[0].blue, 1.0f));
93  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[0], 0.0f));
94  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[1], 0.5f));
95  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[2], 1.0f));
96 }

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

◆ TEST() [346/370]

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

Definition at line 98 of file skia_conversions_unittests.cc.

98  {
99  std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
100  flutter::DlColor::kRed()};
101  std::vector<float> stops = {0.0, .5};
102  const auto gradient =
103  flutter::DlColorSource::MakeLinear(SkPoint::Make(0, 0), //
104  SkPoint::Make(1.0, 1.0), //
105  2, //
106  colors.data(), //
107  stops.data(), //
108  flutter::DlTileMode::kClamp, //
109  nullptr //
110  );
111 
112  std::vector<Color> converted_colors;
113  std::vector<Scalar> converted_stops;
114  skia_conversions::ConvertStops(gradient.get(), converted_colors,
115  converted_stops);
116 
117  // Last color is inserted as red.
118  ASSERT_TRUE(ScalarNearlyEqual(converted_colors[2].red, 1.0f));
119  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[0], 0.0f));
120  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[1], 0.5f));
121  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[2], 1.0f));
122 }

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

◆ TEST() [347/370]

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

Definition at line 46 of file skia_conversions_unittests.cc.

46  {
47  // Typical gradient.
48  std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
49  flutter::DlColor::kRed(),
50  flutter::DlColor::kGreen()};
51  std::vector<float> stops = {0.0, 0.5, 1.0};
52  const auto gradient =
53  flutter::DlColorSource::MakeLinear(SkPoint::Make(0, 0), //
54  SkPoint::Make(1.0, 1.0), //
55  3, //
56  colors.data(), //
57  stops.data(), //
58  flutter::DlTileMode::kClamp, //
59  nullptr //
60  );
61 
62  std::vector<Color> converted_colors;
63  std::vector<Scalar> converted_stops;
64  skia_conversions::ConvertStops(gradient.get(), converted_colors,
65  converted_stops);
66 
67  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[0], 0.0f));
68  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[1], 0.5f));
69  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[2], 1.0f));
70 }

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

◆ TEST() [348/370]

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

Definition at line 124 of file skia_conversions_unittests.cc.

124  {
125  std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
126  flutter::DlColor::kGreen(),
127  flutter::DlColor::kRed()};
128  std::vector<float> stops = {0.0, 100, 1.0};
129  const auto gradient =
130  flutter::DlColorSource::MakeLinear(SkPoint::Make(0, 0), //
131  SkPoint::Make(1.0, 1.0), //
132  3, //
133  colors.data(), //
134  stops.data(), //
135  flutter::DlTileMode::kClamp, //
136  nullptr //
137  );
138 
139  std::vector<Color> converted_colors;
140  std::vector<Scalar> converted_stops;
141  skia_conversions::ConvertStops(gradient.get(), converted_colors,
142  converted_stops);
143 
144  // Value is clamped to 1.0
145  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[0], 0.0f));
146  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[1], 1.0f));
147  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[2], 1.0f));
148 }

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

◆ TEST() [349/370]

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

Definition at line 14 of file skia_conversions_unittests.cc.

14  {
15  for (int x = -100; x < 100; x += 4) {
16  for (int y = -100; y < 100; y += 4) {
17  EXPECT_EQ(skia_conversions::ToPoint(SkPoint::Make(x * 0.25f, y * 0.25f)),
18  Point(x * 0.25f, y * 0.25f));
19  }
20  }
21 }

References impeller::skia_conversions::ToPoint().

◆ TEST() [350/370]

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

Definition at line 23 of file skia_conversions_unittests.cc.

23  {
24  for (int x = -100; x < 100; x += 4) {
25  for (int y = -100; y < 100; y += 4) {
26  EXPECT_EQ(skia_conversions::ToSize(SkPoint::Make(x * 0.25f, y * 0.25f)),
27  Size(x * 0.25f, y * 0.25f));
28  }
29  }
30 }

References impeller::skia_conversions::ToSize().

◆ TEST() [351/370]

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

Definition at line 32 of file skia_conversions_unittests.cc.

32  {
33  // Create a color with alpha, red, green, and blue values that are all
34  // trivially divisible by 255 so that we can test the conversion results in
35  // correct scalar values.
36  // AARRGGBB
37  const flutter::DlColor color = flutter::DlColor(0x8040C020);
38  auto converted_color = skia_conversions::ToColor(color);
39 
40  ASSERT_TRUE(ScalarNearlyEqual(converted_color.alpha, 0x80 * (1.0f / 255)));
41  ASSERT_TRUE(ScalarNearlyEqual(converted_color.red, 0x40 * (1.0f / 255)));
42  ASSERT_TRUE(ScalarNearlyEqual(converted_color.green, 0xC0 * (1.0f / 255)));
43  ASSERT_TRUE(ScalarNearlyEqual(converted_color.blue, 0x20 * (1.0f / 255)));
44 }

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

◆ TEST() [352/370]

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

Definition at line 86 of file base_unittests.cc.

86  {
87  ASSERT_EQ(SPrintF("%sx%d", "Hello", 12), "Hellox12");
88  ASSERT_EQ(SPrintF(""), "");
89  ASSERT_EQ(SPrintF("Hello"), "Hello");
90  ASSERT_EQ(SPrintF("%sx%.2f", "Hello", 12.122222), "Hellox12.12");
91 }

References impeller::SPrintF().

◆ TEST() [353/370]

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

Definition at line 497 of file tessellator_unittests.cc.

497  {
498  auto tessellator = std::make_shared<Tessellator>();
499  PathBuilder builder;
500  builder.AddLine({0, 0}, {100, 100});
501  auto path = builder.TakePath();
502 
503  auto polyline = tessellator->CreateTempPolyline(path, 0.1);
504  EXPECT_DEBUG_DEATH(tessellator->CreateTempPolyline(path, 0.1),
505  "point_buffer_");
506 }

References impeller::PathBuilder::AddLine(), polyline, and impeller::PathBuilder::TakePath().

◆ TEST() [354/370]

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

Definition at line 133 of file tessellator_unittests.cc.

133  {
134  auto tessellator = std::make_shared<Tessellator>();
135 
136  auto test = [&tessellator](const Matrix& transform, Scalar radius) {
137  auto generator = tessellator->FilledCircle(transform, {}, radius);
138  size_t quadrant_divisions = generator.GetVertexCount() / 4;
139 
140  // Confirm the approximation error is within the currently accepted
141  // |kCircleTolerance| value advertised by |CircleTessellator|.
142  // (With an additional 1% tolerance for floating point rounding.)
143  double angle = kPiOver2 / quadrant_divisions;
144  Point first = {radius, 0};
145  Point next = {static_cast<Scalar>(cos(angle) * radius),
146  static_cast<Scalar>(sin(angle) * radius)};
147  Point midpoint = (first + next) * 0.5;
148  EXPECT_GE(midpoint.GetLength(),
149  radius - Tessellator::kCircleTolerance * 1.01)
150  << ", transform = " << transform << ", radius = " << radius
151  << ", divisions = " << quadrant_divisions;
152  };
153 
154  test({}, 0.0);
155  test({}, 0.9);
156  test({}, 1.0);
157  test({}, 1.9);
158  test(Matrix::MakeScale(Vector2(2.0, 2.0)), 0.95);
159  test({}, 2.0);
160  test(Matrix::MakeScale(Vector2(2.0, 2.0)), 1.0);
161  test({}, 11.9);
162  test({}, 12.0);
163  test({}, 35.9);
164  for (int i = 36; i < 10000; i += 4) {
165  test({}, i);
166  }
167 }

References impeller::TPoint< T >::GetLength(), impeller::Tessellator::kCircleTolerance, impeller::kPiOver2, and impeller::Matrix::MakeScale().

◆ TEST() [355/370]

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

Definition at line 483 of file tessellator_unittests.cc.

483  {
484  // This path is not technically empty (it has a size in one dimension),
485  // but is otherwise completely flat.
486  auto tessellator = std::make_shared<Tessellator>();
487  PathBuilder builder;
488  builder.MoveTo({0, 0});
489  builder.MoveTo({10, 10}, /*relative=*/true);
490 
491  auto points = tessellator->TessellateConvex(builder.TakePath(), 3.0);
492 
493  EXPECT_TRUE(points.empty());
494 }

References impeller::PathBuilder::MoveTo(), and impeller::PathBuilder::TakePath().

◆ TEST() [356/370]

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

Definition at line 169 of file tessellator_unittests.cc.

169  {
170  auto tessellator = std::make_shared<Tessellator>();
171 
172  auto test = [&tessellator](const Matrix& transform, const Point& center,
173  Scalar radius) {
174  auto generator = tessellator->FilledCircle(transform, center, radius);
175  EXPECT_EQ(generator.GetTriangleType(), PrimitiveType::kTriangleStrip);
176 
177  auto vertex_count = generator.GetVertexCount();
178  auto vertices = std::vector<Point>();
179  generator.GenerateVertices([&vertices](const Point& p) { //
180  vertices.push_back(p);
181  });
182  EXPECT_EQ(vertices.size(), vertex_count);
183  ASSERT_EQ(vertex_count % 4, 0u);
184 
185  auto quadrant_count = vertex_count / 4;
186  for (size_t i = 0; i < quadrant_count; i++) {
187  double angle = kPiOver2 * i / (quadrant_count - 1);
188  double degrees = angle * 180.0 / kPi;
189  double rsin = sin(angle) * radius;
190  double rcos = cos(angle) * radius;
191  EXPECT_POINT_NEAR(vertices[i * 2],
192  Point(center.x - rcos, center.y + rsin))
193  << "vertex " << i << ", angle = " << degrees << std::endl;
194  EXPECT_POINT_NEAR(vertices[i * 2 + 1],
195  Point(center.x - rcos, center.y - rsin))
196  << "vertex " << i << ", angle = " << degrees << std::endl;
197  EXPECT_POINT_NEAR(vertices[vertex_count - i * 2 - 1],
198  Point(center.x + rcos, center.y - rsin))
199  << "vertex " << i << ", angle = " << degrees << std::endl;
200  EXPECT_POINT_NEAR(vertices[vertex_count - i * 2 - 2],
201  Point(center.x + rcos, center.y + rsin))
202  << "vertex " << i << ", angle = " << degrees << std::endl;
203  }
204  };
205 
206  test({}, {}, 2.0);
207  test({}, {10, 10}, 2.0);
208  test(Matrix::MakeScale({500.0, 500.0, 0.0}), {}, 2.0);
209  test(Matrix::MakeScale({0.002, 0.002, 0.0}), {}, 1000.0);
210 }

References EXPECT_POINT_NEAR, impeller::kPi, impeller::kPiOver2, impeller::kTriangleStrip, and impeller::Matrix::MakeScale().

◆ TEST() [357/370]

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

Definition at line 351 of file tessellator_unittests.cc.

351  {
352  auto tessellator = std::make_shared<Tessellator>();
353 
354  auto test = [&tessellator](const Matrix& transform, const Rect& bounds) {
355  auto center = bounds.GetCenter();
356  auto half_size = bounds.GetSize() * 0.5f;
357 
358  auto generator = tessellator->FilledEllipse(transform, bounds);
359  EXPECT_EQ(generator.GetTriangleType(), PrimitiveType::kTriangleStrip);
360 
361  auto vertex_count = generator.GetVertexCount();
362  auto vertices = std::vector<Point>();
363  generator.GenerateVertices([&vertices](const Point& p) { //
364  vertices.push_back(p);
365  });
366  EXPECT_EQ(vertices.size(), vertex_count);
367  ASSERT_EQ(vertex_count % 4, 0u);
368 
369  auto quadrant_count = vertex_count / 4;
370  for (size_t i = 0; i < quadrant_count; i++) {
371  double angle = kPiOver2 * i / (quadrant_count - 1);
372  double degrees = angle * 180.0 / kPi;
373  double rcos = cos(angle) * half_size.width;
374  double rsin = sin(angle) * half_size.height;
375  EXPECT_POINT_NEAR(vertices[i * 2],
376  Point(center.x - rcos, center.y + rsin))
377  << "vertex " << i << ", angle = " << degrees << ", " //
378  << "bounds = " << bounds << std::endl;
379  EXPECT_POINT_NEAR(vertices[i * 2 + 1],
380  Point(center.x - rcos, center.y - rsin))
381  << "vertex " << i << ", angle = " << degrees << ", " //
382  << "bounds = " << bounds << std::endl;
383  EXPECT_POINT_NEAR(vertices[vertex_count - i * 2 - 1],
384  Point(center.x + rcos, center.y - rsin))
385  << "vertex " << i << ", angle = " << degrees << ", " //
386  << "bounds = " << bounds << std::endl;
387  EXPECT_POINT_NEAR(vertices[vertex_count - i * 2 - 2],
388  Point(center.x + rcos, center.y + rsin))
389  << "vertex " << i << ", angle = " << degrees << ", " //
390  << "bounds = " << bounds << std::endl;
391  }
392  };
393 
394  // Square bounds should actually use the circle generator, but its
395  // results should match the same math as the ellipse generator.
396  test({}, Rect::MakeXYWH(0, 0, 2, 2));
397 
398  test({}, Rect::MakeXYWH(0, 0, 2, 3));
399  test({}, Rect::MakeXYWH(0, 0, 3, 2));
400  test({}, Rect::MakeXYWH(5, 10, 2, 3));
401  test({}, Rect::MakeXYWH(16, 7, 3, 2));
402  test(Matrix::MakeScale({500.0, 500.0, 0.0}), Rect::MakeXYWH(5, 10, 3, 2));
403  test(Matrix::MakeScale({500.0, 500.0, 0.0}), Rect::MakeXYWH(5, 10, 2, 3));
404  test(Matrix::MakeScale({0.002, 0.002, 0.0}),
405  Rect::MakeXYWH(5000, 10000, 3000, 2000));
406  test(Matrix::MakeScale({0.002, 0.002, 0.0}),
407  Rect::MakeXYWH(5000, 10000, 2000, 3000));
408 }

References EXPECT_POINT_NEAR, impeller::kPi, impeller::kPiOver2, impeller::kTriangleStrip, impeller::Matrix::MakeScale(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [358/370]

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

Definition at line 410 of file tessellator_unittests.cc.

410  {
411  auto tessellator = std::make_shared<Tessellator>();
412 
413  auto test = [&tessellator](const Matrix& transform, const Rect& bounds,
414  const Size& radii) {
415  FML_DCHECK(radii.width * 2 <= bounds.GetWidth()) << radii << bounds;
416  FML_DCHECK(radii.height * 2 <= bounds.GetHeight()) << radii << bounds;
417 
418  Scalar middle_left = bounds.GetX() + radii.width;
419  Scalar middle_top = bounds.GetY() + radii.height;
420  Scalar middle_right = bounds.GetX() + bounds.GetWidth() - radii.width;
421  Scalar middle_bottom = bounds.GetY() + bounds.GetHeight() - radii.height;
422 
423  auto generator = tessellator->FilledRoundRect(transform, bounds, radii);
424  EXPECT_EQ(generator.GetTriangleType(), PrimitiveType::kTriangleStrip);
425 
426  auto vertex_count = generator.GetVertexCount();
427  auto vertices = std::vector<Point>();
428  generator.GenerateVertices([&vertices](const Point& p) { //
429  vertices.push_back(p);
430  });
431  EXPECT_EQ(vertices.size(), vertex_count);
432  ASSERT_EQ(vertex_count % 4, 0u);
433 
434  auto quadrant_count = vertex_count / 4;
435  for (size_t i = 0; i < quadrant_count; i++) {
436  double angle = kPiOver2 * i / (quadrant_count - 1);
437  double degrees = angle * 180.0 / kPi;
438  double rcos = cos(angle) * radii.width;
439  double rsin = sin(angle) * radii.height;
440  EXPECT_POINT_NEAR(vertices[i * 2],
441  Point(middle_left - rcos, middle_bottom + rsin))
442  << "vertex " << i << ", angle = " << degrees << ", " //
443  << "bounds = " << bounds << std::endl;
444  EXPECT_POINT_NEAR(vertices[i * 2 + 1],
445  Point(middle_left - rcos, middle_top - rsin))
446  << "vertex " << i << ", angle = " << degrees << ", " //
447  << "bounds = " << bounds << std::endl;
448  EXPECT_POINT_NEAR(vertices[vertex_count - i * 2 - 1],
449  Point(middle_right + rcos, middle_top - rsin))
450  << "vertex " << i << ", angle = " << degrees << ", " //
451  << "bounds = " << bounds << std::endl;
452  EXPECT_POINT_NEAR(vertices[vertex_count - i * 2 - 2],
453  Point(middle_right + rcos, middle_bottom + rsin))
454  << "vertex " << i << ", angle = " << degrees << ", " //
455  << "bounds = " << bounds << std::endl;
456  }
457  };
458 
459  // Both radii spanning the bounds should actually use the circle/ellipse
460  // generator, but their results should match the same math as the round
461  // rect generator.
462  test({}, Rect::MakeXYWH(0, 0, 20, 20), {10, 10});
463 
464  // One radius spanning the bounds, but not the other will not match the
465  // round rect math if the generator transfers to circle/ellipse
466  test({}, Rect::MakeXYWH(0, 0, 20, 20), {10, 5});
467  test({}, Rect::MakeXYWH(0, 0, 20, 20), {5, 10});
468 
469  test({}, Rect::MakeXYWH(0, 0, 20, 30), {2, 2});
470  test({}, Rect::MakeXYWH(0, 0, 30, 20), {2, 2});
471  test({}, Rect::MakeXYWH(5, 10, 20, 30), {2, 3});
472  test({}, Rect::MakeXYWH(16, 7, 30, 20), {2, 3});
473  test(Matrix::MakeScale({500.0, 500.0, 0.0}), Rect::MakeXYWH(5, 10, 30, 20),
474  {2, 3});
475  test(Matrix::MakeScale({500.0, 500.0, 0.0}), Rect::MakeXYWH(5, 10, 20, 30),
476  {2, 3});
477  test(Matrix::MakeScale({0.002, 0.002, 0.0}),
478  Rect::MakeXYWH(5000, 10000, 3000, 2000), {50, 70});
479  test(Matrix::MakeScale({0.002, 0.002, 0.0}),
480  Rect::MakeXYWH(5000, 10000, 2000, 3000), {50, 70});
481 }

References EXPECT_POINT_NEAR, impeller::kPi, impeller::kPiOver2, impeller::kTriangleStrip, impeller::Matrix::MakeScale(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [359/370]

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

Definition at line 280 of file tessellator_unittests.cc.

280  {
281  auto tessellator = std::make_shared<Tessellator>();
282 
283  auto test = [&tessellator](const Matrix& transform, const Point& p0,
284  const Point& p1, Scalar radius) {
285  auto generator = tessellator->RoundCapLine(transform, p0, p1, radius);
286  EXPECT_EQ(generator.GetTriangleType(), PrimitiveType::kTriangleStrip);
287 
288  auto vertex_count = generator.GetVertexCount();
289  auto vertices = std::vector<Point>();
290  generator.GenerateVertices([&vertices](const Point& p) { //
291  vertices.push_back(p);
292  });
293  EXPECT_EQ(vertices.size(), vertex_count);
294  ASSERT_EQ(vertex_count % 4, 0u);
295 
296  Point along = p1 - p0;
297  Scalar length = along.GetLength();
298  if (length > 0) {
299  along *= radius / length;
300  } else {
301  along = {radius, 0};
302  }
303  Point across = {-along.y, along.x};
304 
305  auto quadrant_count = vertex_count / 4;
306  for (size_t i = 0; i < quadrant_count; i++) {
307  double angle = kPiOver2 * i / (quadrant_count - 1);
308  double degrees = angle * 180.0 / kPi;
309  Point relative_along = along * cos(angle);
310  Point relative_across = across * sin(angle);
311  EXPECT_POINT_NEAR(vertices[i * 2], //
312  p0 - relative_along + relative_across)
313  << "vertex " << i << ", angle = " << degrees << ", " //
314  << "line = " << p0 << " => " << p1 << ", " //
315  << "radius = " << radius << std::endl;
316  EXPECT_POINT_NEAR(vertices[i * 2 + 1], //
317  p0 - relative_along - relative_across)
318  << "vertex " << i << ", angle = " << degrees << ", " //
319  << "line = " << p0 << " => " << p1 << ", " //
320  << "radius = " << radius << std::endl;
321  EXPECT_POINT_NEAR(vertices[vertex_count - i * 2 - 1], //
322  p1 + relative_along - relative_across)
323  << "vertex " << i << ", angle = " << degrees << ", " //
324  << "line = " << p0 << " => " << p1 << ", " //
325  << "radius = " << radius << std::endl;
326  EXPECT_POINT_NEAR(vertices[vertex_count - i * 2 - 2], //
327  p1 + relative_along + relative_across)
328  << "vertex " << i << ", angle = " << degrees << ", " //
329  << "line = " << p0 << " => " << p1 << ", " //
330  << "radius = " << radius << std::endl;
331  }
332  };
333 
334  // Empty line should actually use the circle generator, but its
335  // results should match the same math as the round cap generator.
336  test({}, {0, 0}, {0, 0}, 10);
337 
338  test({}, {0, 0}, {10, 0}, 2);
339  test({}, {10, 0}, {0, 0}, 2);
340  test({}, {0, 0}, {10, 10}, 2);
341 
342  test(Matrix::MakeScale({500.0, 500.0, 0.0}), {0, 0}, {10, 0}, 2);
343  test(Matrix::MakeScale({500.0, 500.0, 0.0}), {10, 0}, {0, 0}, 2);
344  test(Matrix::MakeScale({500.0, 500.0, 0.0}), {0, 0}, {10, 10}, 2);
345 
346  test(Matrix::MakeScale({0.002, 0.002, 0.0}), {0, 0}, {10, 0}, 2);
347  test(Matrix::MakeScale({0.002, 0.002, 0.0}), {10, 0}, {0, 0}, 2);
348  test(Matrix::MakeScale({0.002, 0.002, 0.0}), {0, 0}, {10, 10}, 2);
349 }

References EXPECT_POINT_NEAR, impeller::TPoint< T >::GetLength(), impeller::kPi, impeller::kPiOver2, impeller::kTriangleStrip, impeller::Matrix::MakeScale(), impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ TEST() [360/370]

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

Definition at line 212 of file tessellator_unittests.cc.

212  {
213  auto tessellator = std::make_shared<Tessellator>();
214 
215  auto test = [&tessellator](const Matrix& transform, const Point& center,
216  Scalar radius, Scalar half_width) {
217  ASSERT_GT(radius, half_width);
218  auto generator =
219  tessellator->StrokedCircle(transform, center, radius, half_width);
220  EXPECT_EQ(generator.GetTriangleType(), PrimitiveType::kTriangleStrip);
221 
222  auto vertex_count = generator.GetVertexCount();
223  auto vertices = std::vector<Point>();
224  generator.GenerateVertices([&vertices](const Point& p) { //
225  vertices.push_back(p);
226  });
227  EXPECT_EQ(vertices.size(), vertex_count);
228  ASSERT_EQ(vertex_count % 4, 0u);
229 
230  auto quadrant_count = vertex_count / 8;
231 
232  // Test outer points first
233  for (size_t i = 0; i < quadrant_count; i++) {
234  double angle = kPiOver2 * i / (quadrant_count - 1);
235  double degrees = angle * 180.0 / kPi;
236  double rsin = sin(angle) * (radius + half_width);
237  double rcos = cos(angle) * (radius + half_width);
238  EXPECT_POINT_NEAR(vertices[i * 2],
239  Point(center.x - rcos, center.y - rsin))
240  << "vertex " << i << ", angle = " << degrees << std::endl;
241  EXPECT_POINT_NEAR(vertices[quadrant_count * 2 + i * 2],
242  Point(center.x + rsin, center.y - rcos))
243  << "vertex " << i << ", angle = " << degrees << std::endl;
244  EXPECT_POINT_NEAR(vertices[quadrant_count * 4 + i * 2],
245  Point(center.x + rcos, center.y + rsin))
246  << "vertex " << i << ", angle = " << degrees << std::endl;
247  EXPECT_POINT_NEAR(vertices[quadrant_count * 6 + i * 2],
248  Point(center.x - rsin, center.y + rcos))
249  << "vertex " << i << ", angle = " << degrees << std::endl;
250  }
251 
252  // Then test innerer points
253  for (size_t i = 0; i < quadrant_count; i++) {
254  double angle = kPiOver2 * i / (quadrant_count - 1);
255  double degrees = angle * 180.0 / kPi;
256  double rsin = sin(angle) * (radius - half_width);
257  double rcos = cos(angle) * (radius - half_width);
258  EXPECT_POINT_NEAR(vertices[i * 2 + 1],
259  Point(center.x - rcos, center.y - rsin))
260  << "vertex " << i << ", angle = " << degrees << std::endl;
261  EXPECT_POINT_NEAR(vertices[quadrant_count * 2 + i * 2 + 1],
262  Point(center.x + rsin, center.y - rcos))
263  << "vertex " << i << ", angle = " << degrees << std::endl;
264  EXPECT_POINT_NEAR(vertices[quadrant_count * 4 + i * 2 + 1],
265  Point(center.x + rcos, center.y + rsin))
266  << "vertex " << i << ", angle = " << degrees << std::endl;
267  EXPECT_POINT_NEAR(vertices[quadrant_count * 6 + i * 2 + 1],
268  Point(center.x - rsin, center.y + rcos))
269  << "vertex " << i << ", angle = " << degrees << std::endl;
270  }
271  };
272 
273  test({}, {}, 2.0, 1.0);
274  test({}, {}, 2.0, 0.5);
275  test({}, {10, 10}, 2.0, 1.0);
276  test(Matrix::MakeScale({500.0, 500.0, 0.0}), {}, 2.0, 1.0);
277  test(Matrix::MakeScale({0.002, 0.002, 0.0}), {}, 1000.0, 10.0);
278 }

References EXPECT_POINT_NEAR, impeller::kPi, impeller::kPiOver2, impeller::kTriangleStrip, and impeller::Matrix::MakeScale().

◆ TEST() [361/370]

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

Definition at line 107 of file tessellator_unittests.cc.

107  {
108  {
109  Tessellator t;
110  // Sanity check simple rectangle.
111  auto pts = t.TessellateConvex(
112  PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 10, 10)).TakePath(), 1.0);
113 
114  std::vector<Point> expected = {{0, 0}, {10, 0}, {0, 10}, {10, 10}};
115  EXPECT_EQ(pts, expected);
116  }
117 
118  {
119  Tessellator t;
120  auto pts = t.TessellateConvex(PathBuilder{}
121  .AddRect(Rect::MakeLTRB(0, 0, 10, 10))
122  .AddRect(Rect::MakeLTRB(20, 20, 30, 30))
123  .TakePath(),
124  1.0);
125 
126  std::vector<Point> expected = {{0, 0}, {10, 0}, {0, 10}, {10, 10},
127  {10, 10}, {20, 20}, {20, 20}, {30, 20},
128  {20, 30}, {30, 30}};
129  EXPECT_EQ(pts, expected);
130  }
131 }

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

◆ TEST() [362/370]

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

Definition at line 16 of file tessellator_unittests.cc.

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

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

◆ TEST() [363/370]

impeller::testing::TEST ( TextureMTL  ,
CreateFromDrawable   
)

Definition at line 21 of file texture_mtl_unittests.mm.

21  {
22  auto device = MTLCreateSystemDefaultDevice();
23  auto layer = [[CAMetalLayer alloc] init];
24  layer.device = device;
25  layer.drawableSize = CGSize{100, 100};
26  layer.pixelFormat = ToMTLPixelFormat(PixelFormat::kB8G8R8A8UNormInt);
27 
28  TextureDescriptor desc;
29  desc.size = {100, 100};
30  desc.format = PixelFormat::kB8G8R8A8UNormInt;
31  auto drawable_future = GetDrawableDeferred(layer);
32  auto drawable_texture =
33  CreateTextureFromDrawableFuture(desc, drawable_future);
34 
35  ASSERT_TRUE(drawable_texture->IsValid());
36  EXPECT_TRUE(drawable_texture->IsDrawable());
37 
38  // Spawn a thread and acquire the drawable in the thread.
39  auto thread = std::thread([&drawable_texture]() {
40  // Force the drawable to be acquired.
41  drawable_texture->GetMTLTexture();
42  });
43  thread.join();
44  // Block until drawable is acquired.
45  EXPECT_TRUE(drawable_future.get() != nil);
46  // Drawable is cached.
47  EXPECT_TRUE(drawable_texture->GetMTLTexture() != nil);
48  // Once more for good measure.
49  EXPECT_TRUE(drawable_texture->GetMTLTexture() != nil);
50 }

References impeller::CreateTextureFromDrawableFuture(), impeller::TextureDescriptor::format, impeller::GetDrawableDeferred(), impeller::kB8G8R8A8UNormInt, impeller::TextureDescriptor::size, and impeller::ToMTLPixelFormat().

◆ TEST() [364/370]

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

Definition at line 36 of file base_unittests.cc.

36  {
37  Foo f = {};
38 
39  // f.a = 100; <--- Static analysis error.
40  f.mtx.Lock();
41  f.a = 100;
42  f.mtx.Unlock();
43 }

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

◆ TEST() [365/370]

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

Definition at line 45 of file base_unittests.cc.

45  {
46  Foo f = {};
47 
48  // f.a = 100; <--- Static analysis error.
49  auto a = Lock(f.mtx);
50  f.a = 100;
51 }

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

◆ TEST() [366/370]

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

Definition at line 53 of file base_unittests.cc.

53  {
54  RWFoo f = {};
55 
56  // f.a = 100; <--- Static analysis error.
57  f.mtx.LockWriter();
58  f.a = 100;
59  f.mtx.UnlockWriter();
60  // int b = f.a; <--- Static analysis error.
61  f.mtx.LockReader();
62  int b = f.a; // NOLINT(clang-analyzer-deadcode.DeadStores)
63  FML_ALLOW_UNUSED_LOCAL(b);
64  f.mtx.UnlockReader();
65 }

References impeller::saturated::b, and impeller::testing::RWFoo::mtx.

◆ TEST() [367/370]

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

Definition at line 67 of file base_unittests.cc.

67  {
68  RWFoo f = {};
69 
70  // f.a = 100; <--- Static analysis error.
71  {
72  auto write_lock = WriterLock{f.mtx};
73  f.a = 100;
74  }
75 
76  // int b = f.a; <--- Static analysis error.
77  {
78  auto read_lock = ReaderLock(f.mtx);
79  int b = f.a; // NOLINT(clang-analyzer-deadcode.DeadStores)
80  FML_ALLOW_UNUSED_LOCAL(b);
81  }
82 
83  // f.mtx.UnlockReader(); <--- Static analysis error.
84 }

References impeller::saturated::b, and impeller::testing::RWFoo::mtx.

◆ TEST() [368/370]

impeller::testing::TEST ( TraceSerializer  ,
Save   
)

Definition at line 11 of file trace_serializer_unittests.cc.

11  {
12  CanvasRecorder<TraceSerializer> recorder;
13  std::ostringstream ss;
14  fml::LogMessage::CaptureNextLog(&ss);
15  recorder.Save();
16  ASSERT_TRUE(ss.str().size() > 0);
17 }

◆ TEST() [369/370]

impeller::testing::TEST ( TrigTest  ,
MultiplyByScalarRadius   
)

Definition at line 65 of file trig_unittests.cc.

65  {
66  for (int i = 0; i <= 360; i++) {
67  for (int i = 1; i <= 10; i++) {
68  Scalar radius = i * 5.0f;
69  EXPECT_EQ(Trig(Degrees(i)) * radius,
70  Point(radius * std::cos(i * kPi / 180),
71  radius * std::sin(i * kPi / 180)))
72  << "at " << i << " degrees and radius " << radius;
73  }
74  }
75 }

References impeller::kPi.

◆ TEST() [370/370]

impeller::testing::TEST ( TrigTest  ,
TrigAngles   
)

Definition at line 15 of file trig_unittests.cc.

15  {
16  {
17  Trig trig(Degrees(0.0));
18  EXPECT_EQ(trig.cos, 1.0);
19  EXPECT_EQ(trig.sin, 0.0);
20  }
21 
22  {
23  Trig trig(Radians(0.0));
24  EXPECT_EQ(trig.cos, 1.0);
25  EXPECT_EQ(trig.sin, 0.0);
26  }
27 
28  {
29  Trig trig(Degrees(30.0));
30  EXPECT_NEAR(trig.cos, sqrt(0.75), kEhCloseEnough);
31  EXPECT_NEAR(trig.sin, 0.5, kEhCloseEnough);
32  }
33 
34  {
35  Trig trig(Radians(kPi / 6.0));
36  EXPECT_NEAR(trig.cos, sqrt(0.75), kEhCloseEnough);
37  EXPECT_NEAR(trig.sin, 0.5, kEhCloseEnough);
38  }
39 
40  {
41  Trig trig(Degrees(60.0));
42  EXPECT_NEAR(trig.cos, 0.5, kEhCloseEnough);
43  EXPECT_NEAR(trig.sin, sqrt(0.75), kEhCloseEnough);
44  }
45 
46  {
47  Trig trig(Radians(kPi / 3.0));
48  EXPECT_NEAR(trig.cos, 0.5, kEhCloseEnough);
49  EXPECT_NEAR(trig.sin, sqrt(0.75), kEhCloseEnough);
50  }
51 
52  {
53  Trig trig(Degrees(90.0));
54  EXPECT_NEAR(trig.cos, 0.0, kEhCloseEnough);
55  EXPECT_NEAR(trig.sin, 1.0, kEhCloseEnough);
56  }
57 
58  {
59  Trig trig(Radians(kPi / 2.0));
60  EXPECT_NEAR(trig.cos, 0.0, kEhCloseEnough);
61  EXPECT_NEAR(trig.sin, 1.0, kEhCloseEnough);
62  }
63 }

References impeller::Trig::cos, impeller::kEhCloseEnough, impeller::kPi, and impeller::Trig::sin.

◆ TEST_F()

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::MakeXYWH(10, 10, 250, 250), paint);
82  Picture picture = canvas.EndRecordingAsPicture();
83 
84  auto aiks_context =
85  AiksContext(Screenshotter().GetPlayground().GetContext(), nullptr);
86  auto screenshot = Screenshotter().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::testing::Screenshotter::MakeScreenshot(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Paint::stroke_width, and impeller::Paint::style.

◆ TEST_P() [1/419]

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

Definition at line 365 of file aiks_path_unittests.cc.

365  {
366  Canvas canvas;
367  canvas.Scale(GetContentScale());
368 
369  Paint paint;
370  paint.color = Color::Red();
371  std::vector<Color> colors = {Color{1.0, 0.0, 0.0, 1.0},
372  Color{0.0, 0.0, 0.0, 1.0}};
373  std::vector<Scalar> stops = {0.0, 1.0};
374  paint.color_source = ColorSource::MakeSweepGradient(
375  {100, 100}, Degrees(45), Degrees(135), std::move(colors),
376  std::move(stops), Entity::TileMode::kMirror, {});
377  paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
378  .style = FilterContents::BlurStyle::kNormal,
379  .sigma = Sigma(20),
380  };
381 
382  PathBuilder builder;
383  builder.AddArc(Rect::MakeXYWH(10, 10, 100, 100), Degrees(0), Degrees(0),
384  false);
385  canvas.DrawPath(builder.TakePath(), paint);
386 
387  // Check that this empty picture can be created without crashing.
388  canvas.EndRecordingAsPicture();
389 }

References impeller::PathBuilder::AddArc(), impeller::Paint::color, impeller::Paint::color_source, impeller::Canvas::DrawPath(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kMirror, impeller::FilterContents::kNormal, impeller::ColorSource::MakeSweepGradient(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Paint::mask_blur_descriptor, impeller::Color::Red(), impeller::Canvas::Scale(), impeller::Paint::MaskBlurDescriptor::style, and impeller::PathBuilder::TakePath().

◆ TEST_P() [2/419]

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

Definition at line 520 of file aiks_unittests.cc.

520  {
521  Canvas canvas;
522  Paint paint;
523 
524  paint.color = Color::Red();
525  canvas.DrawPaint(paint);
526 
527  paint.blend_mode = BlendMode::kSourceOver;
528  canvas.SaveLayer(paint);
529 
530  paint.color = Color::White();
531  canvas.DrawRect(Rect::MakeXYWH(100, 100, 400, 400), paint);
532 
533  paint.blend_mode = BlendMode::kSource;
534  canvas.SaveLayer(paint);
535 
536  paint.color = Color::Blue();
537  canvas.DrawRect(Rect::MakeXYWH(200, 200, 200, 200), paint);
538 
539  canvas.Restore();
540  canvas.Restore();
541 
542  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
543 }

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::TRect< Scalar >::MakeXYWH(), impeller::Color::Red(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Color::White().

◆ TEST_P() [3/419]

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

Definition at line 201 of file aiks_blur_unittests.cc.

201  {
202  Canvas canvas;
203  canvas.Scale(GetContentScale());
204  canvas.DrawPaint({});
205  Paint blur = {
206  .color = Color::Green(),
207  .mask_blur_descriptor =
208  Paint::MaskBlurDescriptor{
209  .style = FilterContents::BlurStyle::kNormal,
210  .sigma = Sigma(47.6),
211  },
212  };
213  canvas.DrawRect(Rect::MakeXYWH(300, 300, 200, 200), blur);
214  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
215 }

References impeller::Paint::color, impeller::Canvas::DrawPaint(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::FilterContents::kNormal, impeller::TRect< Scalar >::MakeXYWH(), impeller::Canvas::Scale(), and impeller::Paint::MaskBlurDescriptor::style.

◆ TEST_P() [4/419]

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

Definition at line 217 of file aiks_blur_unittests.cc.

217  {
218  Canvas canvas;
219  canvas.Scale(GetContentScale());
220 
221  auto paint_lines = [&canvas](Scalar dx, Scalar dy, Paint paint) {
222  auto draw_line = [&canvas, &paint](Point a, Point b) {
223  canvas.DrawPath(PathBuilder{}.AddLine(a, b).TakePath(), paint);
224  };
225  paint.stroke_width = 5;
226  paint.style = Paint::Style::kStroke;
227  draw_line(Point(dx + 100, dy + 100), Point(dx + 200, dy + 200));
228  draw_line(Point(dx + 100, dy + 200), Point(dx + 200, dy + 100));
229  draw_line(Point(dx + 150, dy + 100), Point(dx + 200, dy + 150));
230  draw_line(Point(dx + 100, dy + 150), Point(dx + 150, dy + 200));
231  };
232 
233  AiksContext renderer(GetContext(), nullptr);
234  Canvas recorder_canvas;
235  for (int x = 0; x < 5; ++x) {
236  for (int y = 0; y < 5; ++y) {
237  Rect rect = Rect::MakeXYWH(x * 20, y * 20, 20, 20);
238  Paint paint{.color =
239  ((x + y) & 1) == 0 ? Color::Yellow() : Color::Blue()};
240  recorder_canvas.DrawRect(rect, paint);
241  }
242  }
243  Picture picture = recorder_canvas.EndRecordingAsPicture();
244  std::shared_ptr<Texture> texture =
245  picture.ToImage(renderer, ISize{100, 100})->GetTexture();
246 
247  ColorSource image_source = ColorSource::MakeImage(
248  texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {}, {});
249  std::shared_ptr<ImageFilter> blur_filter = ImageFilter::MakeBlur(
250  Sigma(5), Sigma(5), FilterContents::BlurStyle::kNormal,
251  Entity::TileMode::kDecal);
252  canvas.DrawRect(Rect::MakeLTRB(0, 0, 300, 600),
253  Paint{.color = Color::DarkGreen()});
254  canvas.DrawRect(Rect::MakeLTRB(100, 100, 200, 200),
255  Paint{.color_source = image_source});
256  canvas.DrawRect(Rect::MakeLTRB(300, 0, 600, 600),
257  Paint{.color = Color::Red()});
258  canvas.DrawRect(
259  Rect::MakeLTRB(400, 100, 500, 200),
260  Paint{.color_source = image_source, .image_filter = blur_filter});
261  paint_lines(0, 300, Paint{.color_source = image_source});
262  paint_lines(300, 300,
263  Paint{.color_source = image_source, .image_filter = blur_filter});
264  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
265 }

References impeller::PathBuilder::AddLine(), impeller::saturated::b, impeller::Color::Blue(), impeller::Paint::color, impeller::Paint::color_source, impeller::Color::DarkGreen(), impeller::Canvas::DrawPath(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kDecal, impeller::FilterContents::kNormal, impeller::Entity::kRepeat, impeller::Paint::kStroke, impeller::ImageFilter::MakeBlur(), impeller::ColorSource::MakeImage(), impeller::TRect< Scalar >::MakeLTRB(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Color::Red(), impeller::Canvas::Scale(), impeller::PathBuilder::TakePath(), impeller::Picture::ToImage(), and impeller::Color::Yellow().

◆ TEST_P() [5/419]

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

Definition at line 136 of file aiks_path_unittests.cc.

136  {
137  Canvas canvas;
138 
139  // Starting at (50, 50), draw lines from:
140  // 1. (50, height)
141  // 2. (width, height)
142  // 3. (width, 50)
143  PathBuilder builder;
144  builder.MoveTo({50, 50});
145  builder.LineTo({50, 100});
146  builder.LineTo({100, 100});
147  builder.LineTo({100, 50});
148 
149  Paint paint;
150  paint.color = Color::Red();
151  paint.style = Paint::Style::kStroke;
152  paint.stroke_width = 10;
153 
154  canvas.DrawPath(builder.TakePath(), paint);
155 
156  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
157 }

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

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

Definition at line 159 of file aiks_path_unittests.cc.

159  {
160  Canvas canvas;
161 
162  // Draw a stroked path that is explicitly closed to verify
163  // It doesn't become a rectangle.
164  PathBuilder builder;
165  builder.MoveTo({50, 50});
166  builder.LineTo({520, 120});
167  builder.LineTo({300, 310});
168  builder.LineTo({100, 50});
169  builder.Close();
170 
171  Paint paint;
172  paint.color = Color::Red();
173  paint.style = Paint::Style::kStroke;
174  paint.stroke_width = 10;
175 
176  canvas.DrawPath(builder.TakePath(), paint);
177 
178  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
179 }

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

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

Definition at line 345 of file aiks_path_unittests.cc.

345  {
346  PathBuilder builder = {};
347  for (auto i = 0; i < 10; i++) {
348  if (i % 2 == 0) {
349  builder.AddCircle(Point(100 + 50 * i, 100 + 50 * i), 100);
350  } else {
351  builder.MoveTo({100.f + 50.f * i - 100, 100.f + 50.f * i});
352  builder.LineTo({100.f + 50.f * i, 100.f + 50.f * i - 100});
353  builder.LineTo({100.f + 50.f * i - 100, 100.f + 50.f * i - 100});
354  builder.Close();
355  }
356  }
357  builder.SetConvexity(Convexity::kConvex);
358 
359  Canvas canvas;
360  canvas.DrawPath(builder.TakePath(), {.color = Color::Red().WithAlpha(0.4)});
361 
362  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
363 }

References impeller::PathBuilder::AddCircle(), impeller::PathBuilder::Close(), impeller::Canvas::DrawPath(), impeller::Canvas::EndRecordingAsPicture(), impeller::kConvex, impeller::PathBuilder::LineTo(), impeller::PathBuilder::MoveTo(), impeller::PathBuilder::SetConvexity(), and impeller::PathBuilder::TakePath().

◆ TEST_P() [8/419]

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

Definition at line 972 of file aiks_unittests.cc.

972  {
973  Canvas canvas;
974  canvas.Scale(Vector2(0.2, 0.2));
975  canvas.DrawPaint({.color = Color::MediumTurquoise()});
976  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
977 }

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

◆ TEST_P() [9/419]

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

Definition at line 979 of file aiks_unittests.cc.

979  {
980  Canvas canvas;
981  canvas.Scale(Vector2(0.2, 0.2));
982  canvas.DrawPaint({.color = Color::MediumTurquoise()});
983  canvas.DrawPaint({.color = Color::Color::OrangeRed().WithAlpha(0.5)});
984  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
985 }

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

◆ TEST_P() [10/419]

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

Definition at line 1057 of file aiks_unittests.cc.

1057  {
1058  auto modes = GetBlendModeSelection();
1059 
1060  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
1061  static Color background = Color::MediumTurquoise();
1062  static Color foreground = Color::Color::OrangeRed().WithAlpha(0.5);
1063  static int current_blend_index = 3;
1064 
1065  if (AiksTest::ImGuiBegin("Controls", nullptr,
1066  ImGuiWindowFlags_AlwaysAutoResize)) {
1067  ImGui::ColorEdit4("Background", reinterpret_cast<float*>(&background));
1068  ImGui::ColorEdit4("Foreground", reinterpret_cast<float*>(&foreground));
1069  ImGui::ListBox("Blend mode", &current_blend_index,
1070  modes.blend_mode_names.data(),
1071  modes.blend_mode_names.size());
1072  ImGui::End();
1073  }
1074 
1075  Canvas canvas;
1076  canvas.Scale(Vector2(0.2, 0.2));
1077  canvas.DrawPaint({.color = background});
1078  canvas.DrawPaint(
1079  {.color = foreground,
1080  .blend_mode = static_cast<BlendMode>(current_blend_index)});
1081  return canvas.EndRecordingAsPicture();
1082  };
1083  ASSERT_TRUE(OpenPlaygroundHere(callback));
1084 }

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

◆ TEST_P() [11/419]

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

Definition at line 987 of file aiks_unittests.cc.

987  {
988  Canvas canvas;
989  canvas.Scale(Vector2(0.2, 0.2));
990  canvas.DrawPaint({.color = Color::MediumTurquoise()});
991  canvas.DrawPaint({.color = Color::Color::OrangeRed().WithAlpha(0.5),
992  .blend_mode = BlendMode::kHue});
993  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
994 }

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

◆ TEST_P() [12/419]

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

Definition at line 3381 of file aiks_unittests.cc.

3381  {
3382  // Avoiding `GetSecondsElapsed()` to reduce risk of golden flakiness.
3383  int time = 0;
3384  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
3385  Canvas canvas;
3386 
3387  canvas.Save();
3388  {
3389  canvas.Translate({300, 300});
3390 
3391  // 1. Draw/restore a clip before drawing the image, which will get drawn
3392  // to the depth buffer behind the image.
3393  canvas.Save();
3394  {
3395  canvas.DrawPaint({.color = Color::Green()});
3396  canvas.ClipRect(Rect::MakeLTRB(-180, -180, 180, 180),
3397  Entity::ClipOperation::kDifference);
3398  canvas.DrawPaint({.color = Color::Black()});
3399  }
3400  canvas.Restore(); // Restore rectangle difference clip.
3401 
3402  canvas.Save();
3403  {
3404  // 2. Draw an oval clip that applies to the image, which will get drawn
3405  // in front of the image on the depth buffer.
3406  canvas.ClipOval(Rect::MakeLTRB(-200, -200, 200, 200));
3407 
3408  // 3. Draw the rotating image with a perspective transform.
3409  canvas.Transform(
3410  Matrix(1.0, 0.0, 0.0, 0.0, //
3411  0.0, 1.0, 0.0, 0.0, //
3412  0.0, 0.0, 1.0, 0.003, //
3413  0.0, 0.0, 0.0, 1.0) * //
3414  Matrix::MakeRotationY({Radians{-1.0f + (time++ / 60.0f)}}));
3415  auto image =
3416  std::make_shared<Image>(CreateTextureForFixture("airplane.jpg"));
3417  canvas.DrawImage(image, -Point(image->GetSize()) / 2, {});
3418  }
3419  canvas.Restore(); // Restore oval intersect clip.
3420 
3421  // 4. Draw a semi-translucent blue circle atop all previous draws.
3422  canvas.DrawCircle({}, 230, {.color = Color::Blue().WithAlpha(0.4)});
3423  }
3424  canvas.Restore(); // Restore translation.
3425 
3426  return canvas.EndRecordingAsPicture();
3427  };
3428  ASSERT_TRUE(OpenPlaygroundHere(callback));
3429 }

References impeller::Color::Black(), impeller::Color::Blue(), impeller::Canvas::ClipOval(), impeller::Canvas::ClipRect(), impeller::Canvas::DrawCircle(), impeller::Canvas::DrawImage(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::Entity::kDifference, impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeRotationY(), impeller::Canvas::Restore(), impeller::Canvas::Save(), impeller::Canvas::Transform(), impeller::Canvas::Translate(), and impeller::Color::WithAlpha().

◆ TEST_P() [13/419]

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

Definition at line 2776 of file aiks_unittests.cc.

2776  {
2777  std::vector<Point> points = {
2778  {0, 0}, //
2779  {100, 100}, //
2780  {100, 0}, //
2781  {0, 100}, //
2782  {0, 0}, //
2783  {48, 48}, //
2784  {52, 52}, //
2785  };
2786  std::vector<PointStyle> caps = {
2787  PointStyle::kRound,
2788  PointStyle::kSquare,
2789  };
2790  Paint paint;
2791  paint.color = Color::Yellow().WithAlpha(0.5);
2792 
2793  Paint background;
2794  background.color = Color::Black();
2795 
2796  Canvas canvas;
2797  canvas.DrawPaint(background);
2798  canvas.Translate({200, 200});
2799  canvas.DrawPoints(points, 10, paint, PointStyle::kRound);
2800  canvas.Translate({150, 0});
2801  canvas.DrawPoints(points, 10, paint, PointStyle::kSquare);
2802 
2803  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2804 }

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

◆ TEST_P() [14/419]

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

Definition at line 2870 of file aiks_unittests.cc.

2870  {
2871  auto texture = CreateTextureForFixture("table_mountain_nx.png",
2872  /*enable_mipmapping=*/true);
2873 
2874  std::vector<Point> points = {
2875  {0, 0}, //
2876  {100, 100}, //
2877  {100, 0}, //
2878  {0, 100}, //
2879  {0, 0}, //
2880  {48, 48}, //
2881  {52, 52}, //
2882  };
2883  std::vector<PointStyle> caps = {
2884  PointStyle::kRound,
2885  PointStyle::kSquare,
2886  };
2887  Paint paint;
2888  paint.color_source = ColorSource::MakeImage(texture, Entity::TileMode::kClamp,
2889  Entity::TileMode::kClamp, {}, {});
2890 
2891  Canvas canvas;
2892  canvas.Translate({200, 200});
2893  canvas.DrawPoints(points, 100, paint, PointStyle::kRound);
2894  canvas.Translate({150, 0});
2895  canvas.DrawPoints(points, 100, paint, PointStyle::kSquare);
2896 
2897  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2898 }

References impeller::Paint::color_source, impeller::Entity::kClamp, impeller::kRound, impeller::kSquare, impeller::ColorSource::MakeImage(), and impeller::Canvas::Translate().

◆ TEST_P() [15/419]

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

Definition at line 501 of file aiks_unittests.cc.

501  {
502  Canvas recorder_canvas;
503 
504  Canvas canvas;
505  AiksContext renderer(GetContext(), nullptr);
506  Paint paint;
507  paint.color = Color::BlackTransparent();
508  canvas.DrawPaint(paint);
509  Picture picture = recorder_canvas.EndRecordingAsPicture();
510  auto image = picture.ToImage(renderer, ISize{1000, 1000});
511  if (image) {
512  canvas.DrawImage(image, Point(), Paint());
513  paint.color = Color{0.1, 0.1, 0.1, 0.2};
514  canvas.DrawRect(Rect::MakeSize(ISize{1000, 1000}), paint);
515  }
516 
517  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
518 }

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

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

Definition at line 610 of file aiks_unittests.cc.

610  {
611  Canvas canvas;
612 
613  Paint red;
614  red.color = Color::Red();
615 
616  canvas.DrawCircle({250, 250}, 125, red);
617 
618  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
619 }

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

◆ TEST_P() [17/419]

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

Definition at line 633 of file aiks_unittests.cc.

633  {
634  Canvas canvas;
635 
636  Paint red;
637  red.color = Color::Red();
638 
639  Paint green;
640  green.color = Color::Green();
641 
642  Paint blue;
643  blue.color = Color::Blue();
644 
645  Paint save;
646  save.color = Color::Black();
647 
648  canvas.SaveLayer(save, Rect::MakeXYWH(0, 0, 50, 50));
649 
650  canvas.DrawRect(Rect::MakeXYWH(0, 0, 100, 100), red);
651  canvas.DrawRect(Rect::MakeXYWH(10, 10, 100, 100), green);
652  canvas.DrawRect(Rect::MakeXYWH(20, 20, 100, 100), blue);
653 
654  canvas.Restore();
655 
656  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
657 }

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

◆ TEST_P() [18/419]

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

Definition at line 659 of file aiks_unittests.cc.

660  {
661  Canvas canvas;
662 
663  Paint red;
664  red.color = Color::Red();
665 
666  Paint green;
667  green.color = Color::Green();
668 
669  Paint blue;
670  blue.color = Color::Blue();
671 
672  Paint save;
673  save.color = Color::Black().WithAlpha(0.5);
674 
675  canvas.SaveLayer(save, Rect::MakeXYWH(0, 0, 100000, 100000));
676 
677  canvas.DrawRect(Rect::MakeXYWH(0, 0, 100, 100), red);
678  canvas.DrawRect(Rect::MakeXYWH(10, 10, 100, 100), green);
679  canvas.DrawRect(Rect::MakeXYWH(20, 20, 100, 100), blue);
680 
681  canvas.Restore();
682 
683  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
684 }

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

◆ TEST_P() [19/419]

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

Definition at line 621 of file aiks_unittests.cc.

621  {
622  Canvas canvas;
623 
624  Paint red;
625  red.color = Color::Red();
626 
627  canvas.Skew(2, 5);
628  canvas.DrawRect(Rect::MakeXYWH(0, 0, 100, 100), red);
629 
630  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
631 }

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

◆ TEST_P() [20/419]

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

Definition at line 475 of file aiks_unittests.cc.

475  {
476  Canvas recorder_canvas;
477  Paint paint;
478  paint.color = Color{0.9568, 0.2627, 0.2118, 1.0};
479  recorder_canvas.DrawRect(Rect::MakeXYWH(100.0, 100.0, 600, 600), paint);
480  paint.color = Color{0.1294, 0.5882, 0.9529, 1.0};
481  recorder_canvas.DrawRect(Rect::MakeXYWH(200.0, 200.0, 600, 600), paint);
482 
483  Canvas canvas;
484  AiksContext renderer(GetContext(), nullptr);
485  paint.color = Color::BlackTransparent();
486  canvas.DrawPaint(paint);
487  Picture picture = recorder_canvas.EndRecordingAsPicture();
488  auto image = picture.ToImage(renderer, ISize{1000, 1000});
489  if (image) {
490  canvas.DrawImage(image, Point(), Paint());
491  paint.color = Color{0.1, 0.1, 0.1, 0.2};
492  canvas.DrawRect(Rect::MakeSize(ISize{1000, 1000}), paint);
493  }
494 
495  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
496 }

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

◆ TEST_P() [21/419]

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

Definition at line 133 of file aiks_unittests.cc.

133  {
134  Canvas canvas;
135 
136  Rect layer_rect = Rect::MakeXYWH(0, 0, 500, 500);
137  canvas.ClipRect(layer_rect);
138 
139  canvas.SaveLayer(
140  {
141  .color_filter = ColorFilter::MakeBlend(BlendMode::kDifference,
142  Color(0, 1, 0, 0.5)),
143  },
144  layer_rect);
145 
146  Paint paint;
147  canvas.DrawPaint({.color = Color::Black()});
148  canvas.DrawRect(Rect::MakeXYWH(100, 100, 300, 300),
149  {.color = Color::White()});
150  canvas.Restore();
151 
152  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
153 }

References impeller::Color::Black(), impeller::Canvas::ClipRect(), impeller::Canvas::DrawPaint(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::kDifference, impeller::ColorFilter::MakeBlend(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Color::White().

◆ TEST_P() [22/419]

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

Definition at line 102 of file aiks_blur_unittests.cc.

102  {
103  Canvas canvas;
104  canvas.DrawCircle({100, 100}, 50, {.color = Color::CornflowerBlue()});
105  canvas.DrawCircle({300, 200}, 100, {.color = Color::GreenYellow()});
106  canvas.DrawCircle({140, 170}, 75, {.color = Color::DarkMagenta()});
107  canvas.DrawCircle({180, 120}, 100, {.color = Color::OrangeRed()});
108  canvas.ClipRRect(Rect::MakeLTRB(75, 50, 375, 275), {20, 20});
109  canvas.SaveLayer({.blend_mode = BlendMode::kSource}, std::nullopt,
110  ImageFilter::MakeBlur(Sigma(30.0), Sigma(30.0),
111  FilterContents::BlurStyle::kNormal,
112  Entity::TileMode::kClamp));
113  canvas.Restore();
114 
115  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
116 }

References impeller::Canvas::ClipRRect(), impeller::Color::CornflowerBlue(), impeller::Color::DarkMagenta(), impeller::Canvas::DrawCircle(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::GreenYellow(), impeller::Entity::kClamp, impeller::FilterContents::kNormal, impeller::kSource, impeller::ImageFilter::MakeBlur(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Color::OrangeRed(), impeller::Canvas::Restore(), and impeller::Canvas::SaveLayer().

◆ TEST_P() [23/419]

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

Definition at line 118 of file aiks_blur_unittests.cc.

118  {
119  Canvas canvas;
120  canvas.DrawCircle({400, 400}, 300, {.color = Color::Green()});
121  canvas.SaveLayer({.blend_mode = BlendMode::kSource}, std::nullopt,
122  ImageFilter::MakeBlur(Sigma(999999), Sigma(999999),
123  FilterContents::BlurStyle::kNormal,
124  Entity::TileMode::kClamp));
125  canvas.Restore();
126 
127  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
128 }

References impeller::Canvas::DrawCircle(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::Entity::kClamp, impeller::FilterContents::kNormal, impeller::kSource, impeller::ImageFilter::MakeBlur(), impeller::Canvas::Restore(), and impeller::Canvas::SaveLayer().

◆ TEST_P() [24/419]

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

Definition at line 78 of file aiks_blur_unittests.cc.

78  {
79  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
80  static PlaygroundPoint point_a(Point(50, 50), 30, Color::White());
81  static PlaygroundPoint point_b(Point(300, 200), 30, Color::White());
82  auto [a, b] = DrawPlaygroundLine(point_a, point_b);
83 
84  Canvas canvas;
85  canvas.DrawCircle({100, 100}, 50, {.color = Color::CornflowerBlue()});
86  canvas.DrawCircle({300, 200}, 100, {.color = Color::GreenYellow()});
87  canvas.DrawCircle({140, 170}, 75, {.color = Color::DarkMagenta()});
88  canvas.DrawCircle({180, 120}, 100, {.color = Color::OrangeRed()});
89  canvas.ClipRRect(Rect::MakeLTRB(a.x, a.y, b.x, b.y), {20, 20});
90  canvas.SaveLayer({.blend_mode = BlendMode::kSource}, std::nullopt,
91  ImageFilter::MakeBlur(Sigma(20.0), Sigma(20.0),
92  FilterContents::BlurStyle::kNormal,
93  Entity::TileMode::kClamp));
94  canvas.Restore();
95 
96  return canvas.EndRecordingAsPicture();
97  };
98 
99  ASSERT_TRUE(OpenPlaygroundHere(callback));
100 }

References impeller::saturated::b, impeller::Canvas::ClipRRect(), impeller::Color::CornflowerBlue(), impeller::Color::DarkMagenta(), impeller::Canvas::DrawCircle(), impeller::DrawPlaygroundLine(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::GreenYellow(), impeller::Entity::kClamp, impeller::FilterContents::kNormal, impeller::kSource, impeller::ImageFilter::MakeBlur(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Color::OrangeRed(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Color::White().

◆ TEST_P() [25/419]

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

Definition at line 3431 of file aiks_unittests.cc.

3431  {
3432  Canvas canvas;
3433  Paint paint;
3434 
3435  canvas.Scale(GetContentScale());
3436 
3437  // Draw something interesting in the background.
3438  std::vector<Color> colors = {Color{0.9568, 0.2627, 0.2118, 1.0},
3439  Color{0.1294, 0.5882, 0.9529, 1.0}};
3440  std::vector<Scalar> stops = {
3441  0.0,
3442  1.0,
3443  };
3444  paint.color_source = ColorSource::MakeLinearGradient(
3445  {0, 0}, {100, 100}, std::move(colors), std::move(stops),
3446  Entity::TileMode::kRepeat, {});
3447  canvas.DrawPaint(paint);
3448 
3449  Rect clip_rect = Rect::MakeLTRB(50, 50, 400, 300);
3450 
3451  // Draw a clipped SaveLayer, where the clip coverage and SaveLayer size are
3452  // the same.
3453  canvas.ClipRRect(clip_rect, Size(100, 100),
3454  Entity::ClipOperation::kIntersect);
3455  canvas.SaveLayer({}, clip_rect,
3456  ImageFilter::MakeFromColorFilter(*ColorFilter::MakeBlend(
3457  BlendMode::kExclusion, Color::Red())));
3458  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3459 }

References impeller::Canvas::ClipRRect(), impeller::Paint::color_source, impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::kExclusion, impeller::Entity::kIntersect, impeller::Entity::kRepeat, impeller::ColorFilter::MakeBlend(), impeller::ImageFilter::MakeFromColorFilter(), impeller::ColorSource::MakeLinearGradient(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Color::Red(), impeller::Canvas::SaveLayer(), and impeller::Canvas::Scale().

◆ TEST_P() [26/419]

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

Definition at line 130 of file aiks_blur_unittests.cc.

130  {
131  Canvas canvas;
132  canvas.ClipRect(Rect::MakeXYWH(100, 150, 400, 400));
133  canvas.DrawCircle(
134  {400, 400}, 200,
135  {
136  .color = Color::Green(),
137  .image_filter = ImageFilter::MakeBlur(
138  Sigma(20.0), Sigma(20.0), FilterContents::BlurStyle::kNormal,
139  Entity::TileMode::kDecal),
140  });
141  canvas.Restore();
142 
143  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
144 }

References impeller::Canvas::ClipRect(), impeller::Canvas::DrawCircle(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::Entity::kDecal, impeller::FilterContents::kNormal, impeller::ImageFilter::MakeBlur(), impeller::TRect< Scalar >::MakeXYWH(), and impeller::Canvas::Restore().

◆ TEST_P() [27/419]

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

Definition at line 1800 of file aiks_unittests.cc.

1800  {
1801  Canvas canvas;
1802 
1803  canvas.DrawPaint({.color = Color::White()});
1804 
1805  // Draw a green circle on the screen.
1806  {
1807  // Increase the clip depth for the savelayer to contend with.
1808  canvas.ClipPath(PathBuilder{}.AddCircle({100, 100}, 50).TakePath());
1809 
1810  canvas.SaveLayer({}, Rect::MakeXYWH(50, 50, 100, 100));
1811 
1812  // Fill the layer with white.
1813  canvas.DrawRect(Rect::MakeSize(Size{400, 400}), {.color = Color::White()});
1814  // Fill the layer with green, but do so with a color blend that can't be
1815  // collapsed into the parent pass.
1816  // TODO(jonahwilliams): this blend mode was changed from color burn to
1817  // hardlight to work around https://github.com/flutter/flutter/issues/136554
1818  // .
1819  canvas.DrawRect(
1820  Rect::MakeSize(Size{400, 400}),
1821  {.color = Color::Green(), .blend_mode = BlendMode::kHardLight});
1822  }
1823 
1824  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1825 }

References impeller::PathBuilder::AddCircle(), impeller::Canvas::ClipPath(), impeller::Canvas::DrawPaint(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::kHardLight, impeller::TRect< Scalar >::MakeSize(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Canvas::SaveLayer(), and impeller::Color::White().

◆ TEST_P() [28/419]

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

Definition at line 2714 of file aiks_unittests.cc.

2714  {
2715  auto runtime_stages =
2716  OpenAssetAsRuntimeStage("runtime_stage_example.frag.iplr");
2717 
2718  auto runtime_stage =
2719  runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
2720  ASSERT_TRUE(runtime_stage);
2721  ASSERT_TRUE(runtime_stage->IsDirty());
2722 
2723  struct FragUniforms {
2724  Vector2 iResolution;
2725  Scalar iTime;
2726  } frag_uniforms = {.iResolution = Vector2(400, 400), .iTime = 100.0};
2727  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
2728  uniform_data->resize(sizeof(FragUniforms));
2729  memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
2730 
2731  std::vector<RuntimeEffectContents::TextureInput> texture_inputs;
2732 
2733  Paint paint;
2734  paint.color_source = ColorSource::MakeRuntimeEffect(
2735  runtime_stage, uniform_data, texture_inputs);
2736 
2737  Canvas canvas;
2738  canvas.Save();
2739  canvas.ClipRRect(Rect::MakeXYWH(0, 0, 400, 400), {10.0, 10.0},
2740  Entity::ClipOperation::kIntersect);
2741  canvas.DrawRect(Rect::MakeXYWH(0, 0, 400, 400), paint);
2742  canvas.Restore();
2743 
2744  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2745 }

References impeller::Canvas::ClipRRect(), impeller::Paint::color_source, impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kIntersect, impeller::ColorSource::MakeRuntimeEffect(), impeller::TRect< Scalar >::MakeXYWH(), impeller::PlaygroundBackendToRuntimeStageBackend(), impeller::Canvas::Restore(), and impeller::Canvas::Save().

◆ TEST_P() [29/419]

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

Definition at line 391 of file aiks_path_unittests.cc.

391  {
392  Canvas canvas;
393  Paint paint;
394  paint.color = Color::Fuchsia();
395  canvas.ClipPath(
396  PathBuilder{}.AddRect(Rect::MakeXYWH(0, 0, 500, 500)).TakePath());
397  canvas.DrawPath(PathBuilder{}.AddCircle({500, 500}, 250).TakePath(), paint);
398  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
399 }

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

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

Definition at line 76 of file aiks_unittests.cc.

76  {
77  Canvas canvas;
78  Paint paint;
79  paint.color = Color::Blue();
80  canvas.DrawPath(PathBuilder{}
81  .AddRect(Rect::MakeXYWH(100.0, 100.0, 100.0, 100.0))
82  .TakePath(),
83  paint);
84  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
85 }

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

◆ TEST_P() [31/419]

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

Definition at line 109 of file aiks_unittests.cc.

109  {
110  Canvas canvas;
111  Paint paint;
112  paint.color = Color::Red();
113  paint.color_filter =
114  ColorFilter::MakeBlend(BlendMode::kSourceOver, Color::Yellow());
115  paint.invert_colors = true;
116 
117  canvas.DrawRect(Rect::MakeLTRB(0, 0, 100, 100), paint);
118  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
119 }

References impeller::Paint::color, impeller::Paint::color_filter, impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Paint::invert_colors, impeller::kSourceOver, impeller::ColorFilter::MakeBlend(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Color::Red(), and impeller::Color::Yellow().

◆ TEST_P() [32/419]

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

Definition at line 121 of file aiks_unittests.cc.

121  {
122  Canvas canvas;
123  Paint paint;
124  paint.color = Color::Red();
125  paint.color_filter =
126  ColorFilter::MakeBlend(BlendMode::kSourceOver, Color::Yellow());
127  paint.invert_colors = true;
128 
129  canvas.DrawPaint(paint);
130  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
131 }

References impeller::Paint::color, impeller::Paint::color_filter, impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::Paint::invert_colors, impeller::kSourceOver, impeller::ColorFilter::MakeBlend(), impeller::Color::Red(), and impeller::Color::Yellow().

◆ TEST_P() [33/419]

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

Definition at line 562 of file aiks_gradient_unittests.cc.

562  {
563  Scalar size = 256;
564  Canvas canvas;
565  Paint paint;
566  paint.color = Color::White();
567  canvas.DrawRect(Rect::MakeXYWH(0, 0, size * 3, size * 3), paint);
568  std::vector<Color> colors = {Color::MakeRGBA8(0xF4, 0x43, 0x36, 0xFF),
569  Color::MakeRGBA8(0xFF, 0xEB, 0x3B, 0xFF),
570  Color::MakeRGBA8(0x4c, 0xAF, 0x50, 0xFF),
571  Color::MakeRGBA8(0x21, 0x96, 0xF3, 0xFF)};
572  std::vector<Scalar> stops = {0.0, 1.f / 3.f, 2.f / 3.f, 1.0};
573  std::array<std::tuple<Point, float, Point, float>, 8> array{
574  std::make_tuple(Point{size / 2.f, size / 2.f}, 0.f,
575  Point{size / 2.f, size / 2.f}, size / 2.f),
576  std::make_tuple(Point{size / 2.f, size / 2.f}, size / 4.f,
577  Point{size / 2.f, size / 2.f}, size / 2.f),
578  std::make_tuple(Point{size / 4.f, size / 4.f}, 0.f,
579  Point{size / 2.f, size / 2.f}, size / 2.f),
580  std::make_tuple(Point{size / 4.f, size / 4.f}, size / 2.f,
581  Point{size / 2.f, size / 2.f}, 0),
582  std::make_tuple(Point{size / 4.f, size / 4.f}, size / 4.f,
583  Point{size / 2.f, size / 2.f}, size / 2.f),
584  std::make_tuple(Point{size / 4.f, size / 4.f}, size / 16.f,
585  Point{size / 2.f, size / 2.f}, size / 8.f),
586  std::make_tuple(Point{size / 4.f, size / 4.f}, size / 8.f,
587  Point{size / 2.f, size / 2.f}, size / 16.f),
588  std::make_tuple(Point{size / 8.f, size / 8.f}, size / 8.f,
589  Point{size / 2.f, size / 2.f}, size / 8.f),
590  };
591  for (int i = 0; i < 8; i++) {
592  canvas.Save();
593  canvas.Translate({(i % 3) * size, i / 3 * size, 0});
594  paint.color_source = ColorSource::MakeConicalGradient(
595  std::get<0>(array[i]), std::get<1>(array[i]), colors, stops,
596  std::get<2>(array[i]), std::get<3>(array[i]), Entity::TileMode::kClamp,
597  {});
598  canvas.DrawRect(Rect::MakeXYWH(0, 0, size, size), paint);
599  canvas.Restore();
600  }
601  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
602 }

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

◆ TEST_P() [34/419]

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

Definition at line 187 of file aiks_gradient_unittests.cc.

187  {
189 }

References CanRenderConicalGradientWithDithering().

◆ TEST_P() [35/419]

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

Definition at line 191 of file aiks_gradient_unittests.cc.

191  {
193 }

References CanRenderConicalGradientWithDithering().

◆ TEST_P() [36/419]

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

Definition at line 56 of file aiks_path_unittests.cc.

56  {
57  Canvas canvas;
58  Paint paint;
59  paint.color = Color::Red();
60  paint.stroke_width = 25.0;
61  paint.style = Paint::Style::kStroke;
62  canvas.DrawPath(PathBuilder{}.AddCircle({500, 500}, 250).TakePath(), paint);
63  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
64 }

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

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

Definition at line 2699 of file aiks_unittests.cc.

2699  {
2700  Canvas canvas;
2701 
2702  canvas.DrawPaint({.color = Color::Red()});
2703  // Draw an empty savelayer with a destructive blend mode, which will replace
2704  // the entire red screen with fully transparent black, except for the green
2705  // circle drawn within the layer.
2706  canvas.SaveLayer({.blend_mode = BlendMode::kSource});
2707  canvas.DrawCircle({300, 300}, 100, {.color = Color::Green()});
2708  canvas.Restore();
2709 
2710  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2711 }

References impeller::Canvas::DrawCircle(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::kSource, impeller::Color::Red(), impeller::Canvas::Restore(), and impeller::Canvas::SaveLayer().

◆ TEST_P() [38/419]

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

Definition at line 352 of file aiks_unittests.cc.

352  {
353  Paint paint;
354  Canvas canvas;
355  canvas.Translate({400, 400});
356 
357  // Limit drawing to face circle with a clip.
358  canvas.ClipPath(PathBuilder{}.AddCircle(Point(), 200).TakePath());
359  canvas.Save();
360 
361  // Cut away eyes/mouth using difference clips.
362  canvas.ClipPath(PathBuilder{}.AddCircle({-100, -50}, 30).TakePath(),
363  Entity::ClipOperation::kDifference);
364  canvas.ClipPath(PathBuilder{}.AddCircle({100, -50}, 30).TakePath(),
365  Entity::ClipOperation::kDifference);
366  canvas.ClipPath(PathBuilder{}
367  .AddQuadraticCurve({-100, 50}, {0, 150}, {100, 50})
368  .TakePath(),
369  Entity::ClipOperation::kDifference);
370 
371  // Draw a huge yellow rectangle to prove the clipping works.
372  paint.color = Color::Yellow();
373  canvas.DrawRect(Rect::MakeXYWH(-1000, -1000, 2000, 2000), paint);
374 
375  // Remove the difference clips and draw hair that partially covers the eyes.
376  canvas.Restore();
377  paint.color = Color::Maroon();
378  canvas.DrawPath(PathBuilder{}
379  .MoveTo({200, -200})
380  .HorizontalLineTo(-200)
381  .VerticalLineTo(-40)
382  .CubicCurveTo({0, -40}, {0, -80}, {200, -80})
383  .TakePath(),
384  paint);
385 
386  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
387 }

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

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

Definition at line 107 of file aiks_path_unittests.cc.

107  {
108  Canvas canvas;
109 
110  Paint paint;
111  paint.color = Color::Red();
112 
113  PathBuilder builder;
114 
115  PathBuilder::RoundingRadii radii;
116  radii.top_left = {50, 25};
117  radii.top_right = {25, 50};
118  radii.bottom_right = {50, 25};
119  radii.bottom_left = {25, 50};
120 
121  builder.AddRoundedRect(Rect::MakeXYWH(100, 100, 200, 200), radii);
122  builder.AddCircle({200, 200}, 50);
123  auto path = builder.TakePath(FillType::kOdd);
124 
125  canvas.DrawImage(
126  std::make_shared<Image>(CreateTextureForFixture("boston.jpg")), {10, 10},
127  Paint{});
128  canvas.DrawPath(path, paint);
129 
130  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
131 }

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::TRect< Scalar >::MakeXYWH(), impeller::Color::Red(), impeller::PathBuilder::TakePath(), impeller::PathBuilder::RoundingRadii::top_left, and impeller::PathBuilder::RoundingRadii::top_right.

◆ TEST_P() [40/419]

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

Definition at line 448 of file aiks_unittests.cc.

448  {
449  Canvas canvas;
450  Paint paint;
451 
452  std::vector<Color> colors = {Color{0.9568, 0.2627, 0.2118, 1.0},
453  Color{0.1294, 0.5882, 0.9529, 1.0}};
454  std::vector<Scalar> stops = {
455  0.0,
456  1.0,
457  };
458 
459  paint.color_source = ColorSource::MakeLinearGradient(
460  {0, 0}, {100, 100}, std::move(colors), std::move(stops),
461  Entity::TileMode::kRepeat, {});
462 
463  canvas.Save();
464  canvas.Translate({100, 100, 0});
465  canvas.DrawRect(Rect::MakeXYWH(0, 0, 200, 200), paint);
466  canvas.Restore();
467 
468  canvas.Save();
469  canvas.Translate({100, 400, 0});
470  canvas.DrawCircle({100, 100}, 100, paint);
471  canvas.Restore();
472  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
473 }

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

◆ TEST_P() [41/419]

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

Definition at line 864 of file aiks_unittests.cc.

864  {
865  Canvas canvas;
866  canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
867 
868  ASSERT_TRUE(RenderTextInCanvasSkia(
869  GetContext(), canvas, "😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊", kFontFixture));
870  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
871 }

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

◆ TEST_P() [42/419]

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

Definition at line 886 of file aiks_unittests.cc.

886  {
887  Canvas canvas;
888  canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
889 
890  ASSERT_TRUE(RenderTextInCanvasSkia(
891  GetContext(), canvas, "😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊", kFontFixture,
892  {.color = Color::Black().WithAlpha(0.5)}));
893  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
894 }

References impeller::Color::Black(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), kFontFixture, RenderTextInCanvasSkia(), and impeller::Color::WithAlpha().

◆ TEST_P() [43/419]

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

Definition at line 873 of file aiks_unittests.cc.

873  {
874  Canvas canvas;
875  canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
876 
877  ASSERT_TRUE(RenderTextInCanvasSkia(
878  GetContext(), canvas, "😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊", kFontFixture,
879  TextRenderOptions{.color = Color::Blue(),
880  .mask_blur_descriptor = Paint::MaskBlurDescriptor{
881  .style = FilterContents::BlurStyle::kNormal,
882  .sigma = Sigma(4)}}));
883  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
884 }

References impeller::Color::Blue(), impeller::testing::TextRenderOptions::color, impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), kFontFixture, impeller::FilterContents::kNormal, RenderTextInCanvasSkia(), and impeller::Paint::MaskBlurDescriptor::style.

◆ TEST_P() [44/419]

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

Definition at line 57 of file aiks_blur_unittests.cc.

57  {
58  // This case triggers the ForegroundAdvancedBlend path. The color filter
59  // should apply to the color only, and respect the alpha mask.
60  Canvas canvas;
61  canvas.ClipRect(Rect::MakeXYWH(100, 150, 400, 400));
62  canvas.DrawCircle({400, 400}, 200,
63  {
64  .color = Color::Grey(),
65  .color_filter = ColorFilter::MakeBlend(
66  BlendMode::kColor, Color::Green()),
67  .mask_blur_descriptor =
68  Paint::MaskBlurDescriptor{
69  .style = FilterContents::BlurStyle::kNormal,
70  .sigma = Radius(20),
71  },
72  });
73  canvas.Restore();
74 
75  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
76 }

References impeller::Canvas::ClipRect(), impeller::Canvas::DrawCircle(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::Color::Grey(), impeller::kColor, impeller::FilterContents::kNormal, impeller::ColorFilter::MakeBlend(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Canvas::Restore(), and impeller::Paint::MaskBlurDescriptor::style.

◆ TEST_P() [45/419]

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

Definition at line 36 of file aiks_blur_unittests.cc.

36  {
37  // This case triggers the ForegroundPorterDuffBlend path. The color filter
38  // should apply to the color only, and respect the alpha mask.
39  Canvas canvas;
40  canvas.ClipRect(Rect::MakeXYWH(100, 150, 400, 400));
41  canvas.DrawCircle({400, 400}, 200,
42  {
43  .color = Color::White(),
44  .color_filter = ColorFilter::MakeBlend(
45  BlendMode::kSource, Color::Green()),
46  .mask_blur_descriptor =
47  Paint::MaskBlurDescriptor{
48  .style = FilterContents::BlurStyle::kNormal,
49  .sigma = Radius(20),
50  },
51  });
52  canvas.Restore();
53 
54  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
55 }

References impeller::Canvas::ClipRect(), impeller::Canvas::DrawCircle(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::FilterContents::kNormal, impeller::kSource, impeller::ColorFilter::MakeBlend(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Canvas::Restore(), impeller::Paint::MaskBlurDescriptor::style, and impeller::Color::White().

◆ TEST_P() [46/419]

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

Definition at line 604 of file aiks_gradient_unittests.cc.

604  {
605  std::vector<Color> colors = {Color::MakeRGBA8(0xF4, 0x43, 0x36, 0xFF),
606  Color::MakeRGBA8(0xFF, 0xEB, 0x3B, 0xFF),
607  Color::MakeRGBA8(0x4c, 0xAF, 0x50, 0xFF),
608  Color::MakeRGBA8(0x21, 0x96, 0xF3, 0xFF)};
609  std::vector<Scalar> stops = {0.0, 1.f / 3.f, 2.f / 3.f, 1.0};
610 
611  std::array<ColorSource, 3> color_sources = {
612  ColorSource::MakeLinearGradient({0, 0}, {100, 100}, colors, stops,
613  Entity::TileMode::kDecal, {}),
614  ColorSource::MakeRadialGradient({100, 100}, 100, colors, stops,
615  Entity::TileMode::kDecal, {}),
616  ColorSource::MakeSweepGradient({100, 100}, Degrees(45), Degrees(135),
617  colors, stops, Entity::TileMode::kDecal,
618  {}),
619  };
620 
621  Canvas canvas;
622  Paint paint;
623  paint.color = Color::White();
624  canvas.DrawRect(Rect::MakeLTRB(0, 0, 605, 205), paint);
625  for (int i = 0; i < 3; i++) {
626  canvas.Save();
627  canvas.Translate({i * 200.0f, 0, 0});
628  paint.color_source = color_sources[i];
629  canvas.DrawRect(Rect::MakeLTRB(0, 0, 200, 200), paint);
630  canvas.Restore();
631  }
632  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
633 }

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

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

Definition at line 545 of file aiks_unittests.cc.

545  {
546  Canvas canvas;
547 
548  Paint red;
549  red.color = Color::Red();
550  Paint green;
551  green.color = Color::Green().WithAlpha(0.5);
552  Paint blue;
553  blue.color = Color::Blue();
554 
555  Paint alpha;
556  alpha.color = Color::Red().WithAlpha(0.5);
557 
558  canvas.SaveLayer(alpha);
559 
560  canvas.DrawRect(Rect::MakeXYWH(000, 000, 100, 100), red);
561  canvas.DrawRect(Rect::MakeXYWH(020, 020, 100, 100), green);
562  canvas.DrawRect(Rect::MakeXYWH(040, 040, 100, 100), blue);
563 
564  canvas.Restore();
565 
566  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
567 }

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

◆ TEST_P() [48/419]

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

Definition at line 87 of file aiks_unittests.cc.

87  {
88  Canvas canvas;
89  Paint paint;
90  auto image = std::make_shared<Image>(CreateTextureForFixture("kalimba.jpg"));
91  paint.color = Color::Red();
92  canvas.DrawImage(image, Point::MakeXY(100.0, 100.0), paint);
93  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
94 }

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

◆ TEST_P() [49/419]

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

Definition at line 244 of file aiks_unittests.cc.

244  {
245  Canvas canvas;
246  Paint paint;
247  auto image = std::make_shared<Image>(CreateTextureForFixture("kalimba.jpg"));
248  Size image_half_size = Size(image->GetSize()) * 0.5;
249 
250  // Render the bottom right quarter of the source image in a stretched rect.
251  auto source_rect = Rect::MakeSize(image_half_size);
252  source_rect = source_rect.Shift(Point(image_half_size));
253 
254  canvas.DrawImageRect(image, source_rect, Rect::MakeXYWH(100, 100, 600, 600),
255  paint);
256  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
257 }

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

◆ TEST_P() [50/419]

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

Definition at line 96 of file aiks_unittests.cc.

96  {
97  Canvas canvas;
98  Paint paint;
99  auto image = std::make_shared<Image>(CreateTextureForFixture("kalimba.jpg"));
100  paint.color = Color::Red();
101  paint.color_filter =
102  ColorFilter::MakeBlend(BlendMode::kSourceOver, Color::Yellow());
103  paint.invert_colors = true;
104 
105  canvas.DrawImage(image, Point::MakeXY(100.0, 100.0), paint);
106  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
107 }

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

◆ TEST_P() [51/419]

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

Definition at line 847 of file aiks_unittests.cc.

847  {
848  Canvas canvas;
849  canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
850 
851  ASSERT_TRUE(RenderTextInCanvasSkia(
852  GetContext(), canvas, "the quick brown fox jumped over the lazy dog!.?",
853  "HomemadeApple.ttf"));
854  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
855 }

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

◆ TEST_P() [52/419]

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

Definition at line 45 of file aiks_gradient_unittests.cc.

45  {
46  CanRenderLinearGradient(this, Entity::TileMode::kClamp);
47 }

References impeller::Entity::kClamp.

◆ TEST_P() [53/419]

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

Definition at line 54 of file aiks_gradient_unittests.cc.

54  {
55  CanRenderLinearGradient(this, Entity::TileMode::kDecal);
56 }

References impeller::Entity::kDecal.

◆ TEST_P() [54/419]

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

Definition at line 58 of file aiks_gradient_unittests.cc.

58  {
59  Canvas canvas;
60  canvas.Scale(GetContentScale());
61  Paint paint;
62  canvas.Translate({100.0f, 0, 0});
63 
64  std::vector<Color> colors = {Color{0.9568, 0.2627, 0.2118, 1.0},
65  Color{0.1294, 0.5882, 0.9529, 0.0}};
66  std::vector<Scalar> stops = {0.0, 1.0};
67 
68  paint.color_source = ColorSource::MakeLinearGradient(
69  {0, 0}, {200, 200}, std::move(colors), std::move(stops),
70  Entity::TileMode::kDecal, {});
71  // Overlay the gradient with 25% green. This should appear as the entire
72  // rectangle being drawn with 25% green, including the border area outside the
73  // decal gradient.
74  paint.color_filter = ColorFilter::MakeBlend(BlendMode::kSourceOver,
75  Color::Green().WithAlpha(0.25));
76 
77  paint.color = Color(1.0, 1.0, 1.0, 1.0);
78  canvas.DrawRect(Rect::MakeXYWH(0, 0, 600, 600), paint);
79  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
80 }

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::TRect< Scalar >::MakeXYWH(), impeller::Canvas::Scale(), and impeller::Canvas::Translate().

◆ TEST_P() [55/419]

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

Definition at line 257 of file aiks_gradient_unittests.cc.

257  {
258  CanRenderLinearGradientManyColors(this, Entity::TileMode::kClamp);
259 }

References impeller::Entity::kClamp.

◆ TEST_P() [56/419]

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

Definition at line 266 of file aiks_gradient_unittests.cc.

266  {
267  CanRenderLinearGradientManyColors(this, Entity::TileMode::kDecal);
268 }

References impeller::Entity::kDecal.

◆ TEST_P() [57/419]

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

Definition at line 263 of file aiks_gradient_unittests.cc.

263  {
264  CanRenderLinearGradientManyColors(this, Entity::TileMode::kMirror);
265 }

References impeller::Entity::kMirror.

◆ TEST_P() [58/419]

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

Definition at line 260 of file aiks_gradient_unittests.cc.

260  {
261  CanRenderLinearGradientManyColors(this, Entity::TileMode::kRepeat);
262 }

References impeller::Entity::kRepeat.

◆ TEST_P() [59/419]

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

Definition at line 300 of file aiks_gradient_unittests.cc.

300  {
301  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
302  const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
303  const Entity::TileMode tile_modes[] = {
304  Entity::TileMode::kClamp, Entity::TileMode::kRepeat,
305  Entity::TileMode::kMirror, Entity::TileMode::kDecal};
306 
307  static int selected_tile_mode = 0;
308  static Matrix matrix = {
309  1, 0, 0, 0, //
310  0, 1, 0, 0, //
311  0, 0, 1, 0, //
312  0, 0, 0, 1 //
313  };
314  if (AiksTest::ImGuiBegin("Controls", nullptr,
315  ImGuiWindowFlags_AlwaysAutoResize)) {
316  ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
317  sizeof(tile_mode_names) / sizeof(char*));
318  std::string label = "##1";
319  for (int i = 0; i < 4; i++) {
320  ImGui::InputScalarN(label.c_str(), ImGuiDataType_Float,
321  &(matrix.vec[i]), 4, NULL, NULL, "%.2f", 0);
322  label[2]++;
323  }
324  ImGui::End();
325  }
326 
327  Canvas canvas;
328  Paint paint;
329  canvas.Translate({100.0, 100.0, 0});
330  auto tile_mode = tile_modes[selected_tile_mode];
331 
332  std::vector<Color> colors = {
333  Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0},
334  Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0},
335  Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0},
336  Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0},
337  Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0},
338  Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0},
339  Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}};
340  std::vector<Scalar> stops = {
341  0.0, 2.0 / 62.0, 4.0 / 62.0, 8.0 / 62.0, 16.0 / 62.0, 32.0 / 62.0, 1.0,
342  };
343 
344  paint.color_source = ColorSource::MakeLinearGradient(
345  {0, 0}, {200, 200}, std::move(colors), std::move(stops), tile_mode, {});
346 
347  canvas.DrawRect(Rect::MakeXYWH(0, 0, 600, 600), paint);
348  return canvas.EndRecordingAsPicture();
349  };
350  ASSERT_TRUE(OpenPlaygroundHere(callback));
351 }

References impeller::Paint::color_source, impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::AiksPlayground::ImGuiBegin(), impeller::Entity::kClamp, impeller::Entity::kDecal, impeller::Entity::kMirror, impeller::Entity::kRepeat, impeller::ColorSource::MakeLinearGradient(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Canvas::Translate(), and impeller::Matrix::vec.

◆ TEST_P() [60/419]

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

Definition at line 353 of file aiks_gradient_unittests.cc.

353  {
354  Canvas canvas;
355 
356  Paint paint = {
357  .color = Color::White(),
358  .color_source = ColorSource::MakeLinearGradient(
359  {200, 200}, {400, 400},
360  {Color::Red(), Color::White(), Color::Red(), Color::White(),
361  Color::Red(), Color::White(), Color::Red(), Color::White(),
362  Color::Red(), Color::White(), Color::Red()},
363  {0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0},
364  Entity::TileMode::kClamp, {}),
365  .mask_blur_descriptor =
366  Paint::MaskBlurDescriptor{
367  .style = FilterContents::BlurStyle::kNormal,
368  .sigma = Sigma(20),
369  },
370  };
371 
372  canvas.DrawCircle({300, 300}, 200, paint);
373  canvas.DrawRect(Rect::MakeLTRB(100, 300, 500, 600), paint);
374 
375  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
376 }

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

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

Definition at line 51 of file aiks_gradient_unittests.cc.

51  {
52  CanRenderLinearGradient(this, Entity::TileMode::kMirror);
53 }

References impeller::Entity::kMirror.

◆ TEST_P() [62/419]

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

Definition at line 48 of file aiks_gradient_unittests.cc.

48  {
49  CanRenderLinearGradient(this, Entity::TileMode::kRepeat);
50 }

References impeller::Entity::kRepeat.

◆ TEST_P() [63/419]

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

Definition at line 296 of file aiks_gradient_unittests.cc.

296  {
297  CanRenderLinearGradientWayManyColors(this, Entity::TileMode::kClamp);
298 }

References impeller::Entity::kClamp.

◆ TEST_P() [64/419]

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

Definition at line 102 of file aiks_gradient_unittests.cc.

102  {
104 }

References CanRenderLinearGradientWithDithering().

◆ TEST_P() [65/419]

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

Definition at line 106 of file aiks_gradient_unittests.cc.

106  {
108 } // namespace

References CanRenderLinearGradientWithDithering().

◆ TEST_P() [66/419]

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

Definition at line 217 of file aiks_gradient_unittests.cc.

217  {
218  CanRenderLinearGradientWithOverlappingStops(this, Entity::TileMode::kClamp);
219 }

References impeller::Entity::kClamp.

◆ TEST_P() [67/419]

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

Definition at line 23 of file aiks_blur_unittests.cc.

23  {
24  Canvas canvas;
25  canvas.DrawCircle({400, 400}, 300,
26  {.color = Color::Green(),
27  .mask_blur_descriptor = Paint::MaskBlurDescriptor{
28  .style = FilterContents::BlurStyle::kNormal,
29  .sigma = Sigma(99999),
30  }});
31  canvas.Restore();
32 
33  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
34 }

References impeller::Canvas::DrawCircle(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::FilterContents::kNormal, impeller::Canvas::Restore(), and impeller::Paint::MaskBlurDescriptor::style.

◆ TEST_P() [68/419]

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

Definition at line 339 of file aiks_unittests.cc.

339  {
340  Canvas canvas;
341  Paint paint;
342  paint.color = Color::Fuchsia();
343  canvas.Save();
344  canvas.ClipPath(PathBuilder{}.AddCircle({200, 400}, 300).TakePath());
345  canvas.Restore();
346  canvas.ClipPath(PathBuilder{}.AddCircle({600, 400}, 300).TakePath());
347  canvas.ClipPath(PathBuilder{}.AddCircle({400, 600}, 300).TakePath());
348  canvas.DrawRect(Rect::MakeXYWH(200, 200, 400, 400), paint);
349  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
350 }

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

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

2649  {
2650  Canvas canvas;
2651  canvas.debug_options.offscreen_texture_checkerboard = true;
2652 
2653  canvas.DrawPaint({.color = Color::AntiqueWhite()});
2654  canvas.DrawCircle({400, 300}, 200,
2655  {.color = Color::CornflowerBlue().WithAlpha(0.75)});
2656 
2657  canvas.SaveLayer({.blend_mode = BlendMode::kMultiply});
2658  {
2659  canvas.DrawCircle({500, 400}, 200,
2660  {.color = Color::DarkBlue().WithAlpha(0.75)});
2661  canvas.DrawCircle({550, 450}, 200,
2662  {.color = Color::LightCoral().WithAlpha(0.75),
2663  .blend_mode = BlendMode::kLuminosity});
2664  }
2665  canvas.Restore();
2666 
2667  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2668 }

References impeller::Color::AntiqueWhite(), impeller::Color::CornflowerBlue(), impeller::Color::DarkBlue(), impeller::Canvas::debug_options, impeller::Canvas::DrawCircle(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::kLuminosity, impeller::kMultiply, impeller::Color::LightCoral(), impeller::Canvas::DebugOptions::offscreen_texture_checkerboard, impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Color::WithAlpha().

◆ TEST_P() [70/419]

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

Definition at line 401 of file aiks_path_unittests.cc.

401  {
402  Canvas canvas;
403 
404  Paint paint;
405  paint.color = Color::Red();
406 
407  PathBuilder::RoundingRadii radii;
408  radii.top_left = {50, 50};
409  radii.top_right = {50, 50};
410  radii.bottom_right = {50, 50};
411  radii.bottom_left = {50, 50};
412 
413  const Scalar kTriangleHeight = 100;
414  canvas.Translate(Vector2(200, 200));
415  // Form a path similar to the Material drop slider value indicator. Both
416  // shapes should render identically side-by-side.
417  {
418  auto path =
419  PathBuilder{}
420  .MoveTo({0, kTriangleHeight})
421  .LineTo({-kTriangleHeight / 2.0f, 0})
422  .LineTo({kTriangleHeight / 2.0f, 0})
423  .Close()
424  .AddRoundedRect(
425  Rect::MakeXYWH(-kTriangleHeight / 2.0f, -kTriangleHeight / 2.0f,
426  kTriangleHeight, kTriangleHeight),
427  radii)
428  .TakePath();
429 
430  canvas.DrawPath(path, paint);
431  }
432  canvas.Translate(Vector2(100, 0));
433  {
434  auto path =
435  PathBuilder{}
436  .MoveTo({0, kTriangleHeight})
437  .LineTo({-kTriangleHeight / 2.0f, 0})
438  .LineTo({0, -10})
439  .LineTo({kTriangleHeight / 2.0f, 0})
440  .Close()
441  .AddRoundedRect(
442  Rect::MakeXYWH(-kTriangleHeight / 2.0f, -kTriangleHeight / 2.0f,
443  kTriangleHeight, kTriangleHeight),
444  radii)
445  .TakePath();
446 
447  canvas.DrawPath(path, paint);
448  }
449 
450  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
451 }

References impeller::PathBuilder::RoundingRadii::bottom_left, impeller::PathBuilder::RoundingRadii::bottom_right, impeller::Close(), impeller::Paint::color, impeller::Canvas::DrawPath(), impeller::Canvas::EndRecordingAsPicture(), impeller::LineTo(), impeller::TRect< Scalar >::MakeXYWH(), impeller::PathBuilder::MoveTo(), impeller::Color::Red(), impeller::PathBuilder::RoundingRadii::top_left, impeller::PathBuilder::RoundingRadii::top_right, and impeller::Canvas::Translate().

◆ TEST_P() [71/419]

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

Definition at line 378 of file aiks_gradient_unittests.cc.

378  {
379  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
380  const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
381  const Entity::TileMode tile_modes[] = {
382  Entity::TileMode::kClamp, Entity::TileMode::kRepeat,
383  Entity::TileMode::kMirror, Entity::TileMode::kDecal};
384 
385  static int selected_tile_mode = 0;
386  static Matrix matrix = {
387  1, 0, 0, 0, //
388  0, 1, 0, 0, //
389  0, 0, 1, 0, //
390  0, 0, 0, 1 //
391  };
392  if (AiksTest::ImGuiBegin("Controls", nullptr,
393  ImGuiWindowFlags_AlwaysAutoResize)) {
394  ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
395  sizeof(tile_mode_names) / sizeof(char*));
396  std::string label = "##1";
397  for (int i = 0; i < 4; i++) {
398  ImGui::InputScalarN(label.c_str(), ImGuiDataType_Float,
399  &(matrix.vec[i]), 4, NULL, NULL, "%.2f", 0);
400  label[2]++;
401  }
402  ImGui::End();
403  }
404 
405  Canvas canvas;
406  Paint paint;
407  canvas.Translate({100.0, 100.0, 0});
408  auto tile_mode = tile_modes[selected_tile_mode];
409 
410  std::vector<Color> colors = {Color{0.9568, 0.2627, 0.2118, 1.0},
411  Color{0.1294, 0.5882, 0.9529, 1.0}};
412  std::vector<Scalar> stops = {0.0, 1.0};
413 
414  paint.color_source = ColorSource::MakeRadialGradient(
415  {100, 100}, 100, std::move(colors), std::move(stops), tile_mode, {});
416 
417  canvas.DrawRect(Rect::MakeXYWH(0, 0, 600, 600), paint);
418  return canvas.EndRecordingAsPicture();
419  };
420  ASSERT_TRUE(OpenPlaygroundHere(callback));
421 }

References impeller::Paint::color_source, impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::AiksPlayground::ImGuiBegin(), impeller::Entity::kClamp, impeller::Entity::kDecal, impeller::Entity::kMirror, impeller::Entity::kRepeat, impeller::ColorSource::MakeRadialGradient(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Canvas::Translate(), and impeller::Matrix::vec.

◆ TEST_P() [72/419]

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

Definition at line 423 of file aiks_gradient_unittests.cc.

423  {
424  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
425  const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
426  const Entity::TileMode tile_modes[] = {
427  Entity::TileMode::kClamp, Entity::TileMode::kRepeat,
428  Entity::TileMode::kMirror, Entity::TileMode::kDecal};
429 
430  static int selected_tile_mode = 0;
431  static Matrix matrix = {
432  1, 0, 0, 0, //
433  0, 1, 0, 0, //
434  0, 0, 1, 0, //
435  0, 0, 0, 1 //
436  };
437  if (AiksTest::ImGuiBegin("Controls", nullptr,
438  ImGuiWindowFlags_AlwaysAutoResize)) {
439  ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
440  sizeof(tile_mode_names) / sizeof(char*));
441  std::string label = "##1";
442  for (int i = 0; i < 4; i++) {
443  ImGui::InputScalarN(label.c_str(), ImGuiDataType_Float,
444  &(matrix.vec[i]), 4, NULL, NULL, "%.2f", 0);
445  label[2]++;
446  }
447  ImGui::End();
448  }
449 
450  Canvas canvas;
451  Paint paint;
452  canvas.Translate({100.0, 100.0, 0});
453  auto tile_mode = tile_modes[selected_tile_mode];
454 
455  std::vector<Color> colors = {
456  Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0},
457  Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0},
458  Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0},
459  Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0},
460  Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0},
461  Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0},
462  Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}};
463  std::vector<Scalar> stops = {
464  0.0,
465  (1.0 / 6.0) * 1,
466  (1.0 / 6.0) * 2,
467  (1.0 / 6.0) * 3,
468  (1.0 / 6.0) * 4,
469  (1.0 / 6.0) * 5,
470  1.0,
471  };
472 
473  paint.color_source = ColorSource::MakeRadialGradient(
474  {100, 100}, 100, std::move(colors), std::move(stops), tile_mode, {});
475 
476  canvas.DrawRect(Rect::MakeXYWH(0, 0, 600, 600), paint);
477  return canvas.EndRecordingAsPicture();
478  };
479  ASSERT_TRUE(OpenPlaygroundHere(callback));
480 }

References impeller::Paint::color_source, impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::AiksPlayground::ImGuiBegin(), impeller::Entity::kClamp, impeller::Entity::kDecal, impeller::Entity::kMirror, impeller::Entity::kRepeat, impeller::ColorSource::MakeRadialGradient(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Canvas::Translate(), and impeller::Matrix::vec.

◆ TEST_P() [73/419]

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

Definition at line 129 of file aiks_gradient_unittests.cc.

129  {
131 }

References CanRenderRadialGradientWithDithering().

◆ TEST_P() [74/419]

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

Definition at line 133 of file aiks_gradient_unittests.cc.

133  {
135 }

References CanRenderRadialGradientWithDithering().

◆ TEST_P() [75/419]

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

Definition at line 686 of file aiks_unittests.cc.

686  {
687  Canvas canvas;
688 
689  Paint paint;
690  paint.color = Color::Red();
691 
692  PathBuilder::RoundingRadii radii;
693  radii.top_left = {50, 25};
694  radii.top_right = {25, 50};
695  radii.bottom_right = {50, 25};
696  radii.bottom_left = {25, 50};
697 
698  auto path = PathBuilder{}
699  .AddRoundedRect(Rect::MakeXYWH(100, 100, 500, 500), radii)
700  .TakePath();
701 
702  canvas.DrawPath(path, paint);
703 
704  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
705 }

References impeller::PathBuilder::AddRoundedRect(), impeller::PathBuilder::RoundingRadii::bottom_left, impeller::PathBuilder::RoundingRadii::bottom_right, impeller::Paint::color, impeller::Canvas::DrawPath(), impeller::Canvas::EndRecordingAsPicture(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Color::Red(), impeller::PathBuilder::TakePath(), impeller::PathBuilder::RoundingRadii::top_left, and impeller::PathBuilder::RoundingRadii::top_right.

◆ TEST_P() [76/419]

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

Definition at line 259 of file aiks_unittests.cc.

259  {
260  Canvas canvas;
261  canvas.Scale(GetContentScale());
262  Paint paint;
263 
264  paint.color = Color::White();
265  canvas.DrawPaint(paint);
266 
267  auto draw = [&canvas](const Paint& paint, Scalar x, Scalar y) {
268  canvas.Save();
269  canvas.Translate({x, y});
270  {
271  canvas.Save();
272  canvas.ClipRect(Rect::MakeLTRB(50, 50, 150, 150));
273  canvas.DrawPaint(paint);
274  canvas.Restore();
275  }
276  {
277  canvas.Save();
278  canvas.ClipOval(Rect::MakeLTRB(200, 50, 300, 150));
279  canvas.DrawPaint(paint);
280  canvas.Restore();
281  }
282  {
283  canvas.Save();
284  canvas.ClipRRect(Rect::MakeLTRB(50, 200, 150, 300), {20, 20});
285  canvas.DrawPaint(paint);
286  canvas.Restore();
287  }
288  {
289  canvas.Save();
290  canvas.ClipRRect(Rect::MakeLTRB(200, 230, 300, 270), {20, 20});
291  canvas.DrawPaint(paint);
292  canvas.Restore();
293  }
294  {
295  canvas.Save();
296  canvas.ClipRRect(Rect::MakeLTRB(230, 200, 270, 300), {20, 20});
297  canvas.DrawPaint(paint);
298  canvas.Restore();
299  }
300  canvas.Restore();
301  };
302 
303  paint.color = Color::Blue();
304  draw(paint, 0, 0);
305 
306  std::vector<Color> gradient_colors = {
307  Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0},
308  Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0},
309  Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0},
310  Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0},
311  Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0},
312  Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0},
313  Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}};
314  std::vector<Scalar> stops = {
315  0.0,
316  (1.0 / 6.0) * 1,
317  (1.0 / 6.0) * 2,
318  (1.0 / 6.0) * 3,
319  (1.0 / 6.0) * 4,
320  (1.0 / 6.0) * 5,
321  1.0,
322  };
323  auto texture = CreateTextureForFixture("airplane.jpg",
324  /*enable_mipmapping=*/true);
325 
326  paint.color_source = ColorSource::MakeRadialGradient(
327  {500, 600}, 75, std::move(gradient_colors), std::move(stops),
328  Entity::TileMode::kMirror, {});
329  draw(paint, 0, 300);
330 
331  paint.color_source = ColorSource::MakeImage(
332  texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {},
333  Matrix::MakeTranslation({0, 0}));
334  draw(paint, 300, 0);
335 
336  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
337 }

References impeller::Color::Blue(), impeller::Canvas::ClipOval(), impeller::Canvas::ClipRect(), impeller::Canvas::ClipRRect(), impeller::Paint::color, impeller::Paint::color_source, impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kMirror, impeller::Entity::kRepeat, impeller::ColorSource::MakeImage(), impeller::TRect< Scalar >::MakeLTRB(), impeller::ColorSource::MakeRadialGradient(), impeller::Matrix::MakeTranslation(), impeller::Canvas::Restore(), impeller::Canvas::Save(), impeller::Canvas::Scale(), impeller::Canvas::Translate(), and impeller::Color::White().

◆ TEST_P() [77/419]

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

Definition at line 76 of file aiks_path_unittests.cc.

76  {
77  Canvas canvas;
78 
79  Paint paint;
80  paint.color = Color::Red();
81  paint.style = Paint::Style::kStroke;
82  paint.stroke_width = 200;
83 
84  Rect rect = Rect::MakeXYWH(100, 100, 200, 200);
85  PathBuilder builder;
86  builder.AddArc(rect, Degrees(0), Degrees(90), false);
87 
88  canvas.DrawPath(builder.TakePath(), paint);
89  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
90 }

References impeller::PathBuilder::AddArc(), impeller::Paint::color, impeller::Canvas::DrawPath(), impeller::Canvas::EndRecordingAsPicture(), impeller::Paint::kStroke, impeller::TRect< Scalar >::MakeXYWH(), impeller::Color::Red(), impeller::Paint::stroke_width, impeller::Paint::style, and impeller::PathBuilder::TakePath().

◆ TEST_P() [78/419]

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

Definition at line 92 of file aiks_path_unittests.cc.

92  {
93  Canvas canvas;
94 
95  Paint paint;
96  paint.color = Color::Red();
97  paint.style = Paint::Style::kStroke;
98  paint.stroke_width = 20;
99 
100  PathBuilder builder;
101  builder.AddCubicCurve({0, 200}, {50, 400}, {350, 0}, {400, 200});
102 
103  canvas.DrawPath(builder.TakePath(), paint);
104  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
105 }

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

◆ TEST_P() [79/419]

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

Definition at line 45 of file aiks_path_unittests.cc.

45  {
46  Canvas canvas;
47  Paint paint;
48  paint.color = Color::Red();
49  paint.stroke_width = 20.0;
50  paint.style = Paint::Style::kStroke;
51  canvas.DrawPath(PathBuilder{}.AddLine({200, 100}, {800, 100}).TakePath(),
52  paint);
53  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
54 }

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

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

Definition at line 502 of file aiks_gradient_unittests.cc.

502  {
503  CanRenderSweepGradient(this, Entity::TileMode::kClamp);
504 }

References impeller::Entity::kClamp.

◆ TEST_P() [81/419]

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

Definition at line 511 of file aiks_gradient_unittests.cc.

511  {
512  CanRenderSweepGradient(this, Entity::TileMode::kDecal);
513 }

References impeller::Entity::kDecal.

◆ TEST_P() [82/419]

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

Definition at line 549 of file aiks_gradient_unittests.cc.

549  {
550  CanRenderSweepGradientManyColors(this, Entity::TileMode::kClamp);
551 }

References impeller::Entity::kClamp.

◆ TEST_P() [83/419]

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

Definition at line 558 of file aiks_gradient_unittests.cc.

558  {
559  CanRenderSweepGradientManyColors(this, Entity::TileMode::kDecal);
560 }

References impeller::Entity::kDecal.

◆ TEST_P() [84/419]

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

Definition at line 555 of file aiks_gradient_unittests.cc.

555  {
556  CanRenderSweepGradientManyColors(this, Entity::TileMode::kMirror);
557 }

References impeller::Entity::kMirror.

◆ TEST_P() [85/419]

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

Definition at line 552 of file aiks_gradient_unittests.cc.

552  {
553  CanRenderSweepGradientManyColors(this, Entity::TileMode::kRepeat);
554 }

References impeller::Entity::kRepeat.

◆ TEST_P() [86/419]

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

Definition at line 508 of file aiks_gradient_unittests.cc.

508  {
509  CanRenderSweepGradient(this, Entity::TileMode::kMirror);
510 }

References impeller::Entity::kMirror.

◆ TEST_P() [87/419]

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

Definition at line 505 of file aiks_gradient_unittests.cc.

505  {
506  CanRenderSweepGradient(this, Entity::TileMode::kRepeat);
507 }

References impeller::Entity::kRepeat.

◆ TEST_P() [88/419]

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

Definition at line 158 of file aiks_gradient_unittests.cc.

158  {
160 }

References CanRenderSweepGradientWithDithering().

◆ TEST_P() [89/419]

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

Definition at line 162 of file aiks_gradient_unittests.cc.

162  {
164 }

References CanRenderSweepGradientWithDithering().

◆ TEST_P() [90/419]

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

Definition at line 781 of file aiks_unittests.cc.

781  {
782  Canvas canvas;
783  canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
784  ASSERT_TRUE(RenderTextInCanvasSkia(
785  GetContext(), canvas, "the quick brown fox jumped over the lazy dog!.?",
786  "Roboto-Regular.ttf"));
787  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
788 }

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

◆ TEST_P() [91/419]

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

Definition at line 790 of file aiks_unittests.cc.

790  {
791  Canvas canvas;
792  canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
793  ASSERT_TRUE(RenderTextInCanvasSTB(
794  GetContext(), canvas, "the quick brown fox jumped over the lazy dog!.?",
795  "Roboto-Regular.ttf"));
796 
797  SetTypographerContext(TypographerContextSTB::Make());
798  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
799 }

References impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::TypographerContextSTB::Make(), and RenderTextInCanvasSTB().

◆ TEST_P() [92/419]

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

Definition at line 896 of file aiks_unittests.cc.

896  {
897  Canvas canvas;
898  canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
899 
900  canvas.Translate({100, 100});
901  canvas.Scale(Vector2{0.5, 0.5});
902 
903  // Blend the layer with the parent pass using kClear to expose the coverage.
904  canvas.SaveLayer({.blend_mode = BlendMode::kClear});
905  ASSERT_TRUE(RenderTextInCanvasSkia(
906  GetContext(), canvas, "the quick brown fox jumped over the lazy dog!.?",
907  "Roboto-Regular.ttf"));
908  canvas.Restore();
909 
910  // Render the text again over the cleared coverage rect.
911  ASSERT_TRUE(RenderTextInCanvasSkia(
912  GetContext(), canvas, "the quick brown fox jumped over the lazy dog!.?",
913  "Roboto-Regular.ttf"));
914 
915  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
916 }

References impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::kClear, RenderTextInCanvasSkia(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), impeller::Canvas::Scale(), and impeller::Canvas::Translate().

◆ TEST_P() [93/419]

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

Definition at line 918 of file aiks_unittests.cc.

918  {
919  Canvas canvas;
920  canvas.Translate({200, 150});
921 
922  // Construct the text blob.
923  auto mapping = flutter::testing::OpenFixtureAsSkData("wtf.otf");
924  ASSERT_NE(mapping, nullptr);
925 
926  Scalar font_size = 80;
927  sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
928  SkFont sk_font(font_mgr->makeFromData(mapping), font_size);
929 
930  Paint text_paint;
931  text_paint.color = Color::Blue().WithAlpha(0.8);
932 
933  struct {
934  Point position;
935  const char* text;
936  } text[] = {{Point(0, 0), "0F0F0F0"},
937  {Point(1, 2), "789"},
938  {Point(1, 3), "456"},
939  {Point(1, 4), "123"},
940  {Point(0, 6), "0F0F0F0"}};
941  for (auto& t : text) {
942  canvas.Save();
943  canvas.Translate(t.position * Point(font_size * 2, font_size * 1.1));
944  {
945  auto blob = SkTextBlob::MakeFromString(t.text, sk_font);
946  ASSERT_NE(blob, nullptr);
947  auto frame = MakeTextFrameFromTextBlobSkia(blob);
948  canvas.DrawTextFrame(frame, Point(), text_paint);
949  }
950  canvas.Restore();
951  }
952 
953  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
954 }

References impeller::Color::Blue(), impeller::Paint::color, impeller::Canvas::DrawTextFrame(), impeller::Canvas::EndRecordingAsPicture(), impeller::MakeTextFrameFromTextBlobSkia(), impeller::Canvas::Restore(), impeller::Canvas::Save(), impeller::Canvas::Translate(), and impeller::Color::WithAlpha().

◆ TEST_P() [94/419]

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

Definition at line 66 of file aiks_path_unittests.cc.

66  {
67  Canvas canvas;
68  Paint paint;
69  paint.color = Color::Red();
70  paint.stroke_width = 100.0;
71  paint.style = Paint::Style::kStroke;
72  canvas.DrawPath(PathBuilder{}.AddCircle({100, 100}, 50).TakePath(), paint);
73  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
74 }

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

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

Definition at line 223 of file aiks_unittests.cc.

223  {
224  CanRenderTiledTexture(this, Entity::TileMode::kClamp);
225 }

References impeller::Entity::kClamp.

◆ TEST_P() [96/419]

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

Definition at line 239 of file aiks_unittests.cc.

239  {
240  CanRenderTiledTexture(this, Entity::TileMode::kClamp,
241  Matrix::MakeTranslation({172.f, 172.f, 0.f}));
242 }

References impeller::Entity::kClamp, and impeller::Matrix::MakeTranslation().

◆ TEST_P() [97/419]

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

Definition at line 235 of file aiks_unittests.cc.

235  {
236  CanRenderTiledTexture(this, Entity::TileMode::kDecal);
237 }

References impeller::Entity::kDecal.

◆ TEST_P() [98/419]

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

Definition at line 231 of file aiks_unittests.cc.

231  {
232  CanRenderTiledTexture(this, Entity::TileMode::kMirror);
233 }

References impeller::Entity::kMirror.

◆ TEST_P() [99/419]

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

Definition at line 227 of file aiks_unittests.cc.

227  {
228  CanRenderTiledTexture(this, Entity::TileMode::kRepeat);
229 }

References impeller::Entity::kRepeat.

◆ TEST_P() [100/419]

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

2629  {
2630  Canvas canvas;
2631  canvas.DrawPaint({.color = Color::Red()});
2632 
2633  // Draw two overlapping subpixel circles.
2634  canvas.SaveLayer({});
2635  canvas.DrawCircle({100, 100}, 0.1, {.color = Color::Yellow()});
2636  canvas.Restore();
2637  canvas.SaveLayer({});
2638  canvas.DrawCircle({100, 100}, 0.1, {.color = Color::Yellow()});
2639  canvas.Restore();
2640 
2641  canvas.DrawPaint({.color = Color::Green()});
2642 
2643  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2644 }

References impeller::Canvas::DrawCircle(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::Color::Red(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Color::Yellow().

◆ TEST_P() [101/419]

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

Definition at line 389 of file aiks_unittests.cc.

389  {
390  Canvas canvas;
391 
392  // Cover the whole canvas with red.
393  canvas.DrawPaint({.color = Color::Red()});
394 
395  canvas.Save();
396 
397  // Append two clips, the second resulting in empty coverage.
398  canvas.ClipPath(
399  PathBuilder{}.AddRect(Rect::MakeXYWH(100, 100, 100, 100)).TakePath());
400  canvas.ClipPath(
401  PathBuilder{}.AddRect(Rect::MakeXYWH(300, 300, 100, 100)).TakePath());
402 
403  // Restore to no clips.
404  canvas.Restore();
405 
406  // Replace the whole canvas with green.
407  canvas.DrawPaint({.color = Color::Green()});
408 
409  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
410 }

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

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

Definition at line 430 of file aiks_unittests.cc.

430  {
431  Canvas canvas;
432 
433  Paint red;
434  red.color = Color::Red();
435 
436  Paint alpha;
437  alpha.color = Color::Red().WithAlpha(0.5);
438 
439  canvas.SaveLayer(alpha);
440 
441  canvas.DrawCircle({125, 125}, 125, red);
442 
443  canvas.Restore();
444 
445  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
446 }

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

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

Definition at line 60 of file aiks_unittests.cc.

60  {
61  Canvas canvas;
62  ASSERT_EQ(canvas.GetSaveCount(), 1u);
63  ASSERT_EQ(canvas.Restore(), false);
64 
65  canvas.Translate(Size{100, 100});
66  canvas.Save();
67  ASSERT_EQ(canvas.GetSaveCount(), 2u);
68  ASSERT_MATRIX_NEAR(canvas.GetCurrentTransform(),
69  Matrix::MakeTranslation({100.0, 100.0, 0.0}));
70  ASSERT_TRUE(canvas.Restore());
71  ASSERT_EQ(canvas.GetSaveCount(), 1u);
72  ASSERT_MATRIX_NEAR(canvas.GetCurrentTransform(),
73  Matrix::MakeTranslation({100.0, 100.0, 0.0}));
74 }

References ASSERT_MATRIX_NEAR, impeller::Canvas::GetCurrentTransform(), impeller::Canvas::GetSaveCount(), impeller::Matrix::MakeTranslation(), impeller::Canvas::Restore(), impeller::Canvas::Save(), and impeller::Canvas::Translate().

◆ TEST_P() [104/419]

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

Definition at line 51 of file aiks_unittests.cc.

51  {
52  Canvas canvas;
53  Matrix identity;
54  ASSERT_MATRIX_NEAR(canvas.GetCurrentTransform(), identity);
55  canvas.Translate(Size{100, 100});
56  ASSERT_MATRIX_NEAR(canvas.GetCurrentTransform(),
57  Matrix::MakeTranslation({100.0, 100.0, 0.0}));
58 }

References ASSERT_MATRIX_NEAR, impeller::Canvas::GetCurrentTransform(), impeller::Matrix::MakeTranslation(), and impeller::Canvas::Translate().

◆ TEST_P() [105/419]

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

Definition at line 3050 of file aiks_unittests.cc.

3050  {
3051  auto capture_context = CaptureContext::MakeAllowlist({"TestDocument"});
3052 
3053  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
3054  Canvas canvas;
3055 
3056  capture_context.Rewind();
3057  auto document = capture_context.GetDocument("TestDocument");
3058 
3059  auto color = document.AddColor("Background color", Color::CornflowerBlue());
3060  canvas.DrawPaint({.color = color});
3061 
3062  if (AiksTest::ImGuiBegin("TestDocument", nullptr,
3063  ImGuiWindowFlags_AlwaysAutoResize)) {
3064  document.GetElement()->properties.Iterate([](CaptureProperty& property) {
3065  property.Invoke({.color = [](CaptureColorProperty& p) {
3066  ImGui::ColorEdit4(p.label.c_str(),
3067  reinterpret_cast<float*>(&p.value));
3068  }});
3069  });
3070  ImGui::End();
3071  }
3072 
3073  return canvas.EndRecordingAsPicture();
3074  };
3075  OpenPlaygroundHere(callback);
3076 }

References impeller::Color::CornflowerBlue(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::AiksPlayground::ImGuiBegin(), and impeller::CaptureContext::MakeAllowlist().

◆ TEST_P() [106/419]

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

Definition at line 3078 of file aiks_unittests.cc.

3078  {
3079  ASSERT_FALSE(GetContext()->capture.IsActive());
3080 }

◆ TEST_P() [107/419]

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

Definition at line 3160 of file aiks_unittests.cc.

3160  {
3161  Canvas canvas;
3162  Paint white;
3163  white.color = Color::Blue();
3164  canvas.DrawRect(Rect::MakeXYWH(0, 0, 600.0, 600.0), white);
3165 
3166  Paint clear;
3167  clear.blend_mode = BlendMode::kClear;
3168 
3169  canvas.DrawCircle(Point::MakeXY(300.0, 300.0), 200.0, clear);
3170 }

References impeller::Paint::blend_mode, impeller::Color::Blue(), impeller::Paint::color, impeller::Canvas::DrawCircle(), impeller::Canvas::DrawRect(), impeller::kClear, impeller::TPoint< Scalar >::MakeXY(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST_P() [108/419]

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

Definition at line 183 of file aiks_blur_unittests.cc.

183  {
184  Canvas canvas;
185  Paint white;
186  white.color = Color::Blue();
187  canvas.DrawRect(Rect::MakeXYWH(0, 0, 600.0, 600.0), white);
188 
189  Paint clear;
190  clear.blend_mode = BlendMode::kClear;
191  clear.mask_blur_descriptor = Paint::MaskBlurDescriptor{
192  .style = FilterContents::BlurStyle::kNormal,
193  .sigma = Sigma(20),
194  };
195 
196  canvas.DrawCircle(Point::MakeXY(300.0, 300.0), 200.0, clear);
197 
198  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
199 }

References impeller::Paint::blend_mode, impeller::Color::Blue(), impeller::Paint::color, impeller::Canvas::DrawCircle(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::kClear, impeller::FilterContents::kNormal, impeller::TPoint< Scalar >::MakeXY(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Paint::mask_blur_descriptor, and impeller::Paint::MaskBlurDescriptor::style.

◆ TEST_P() [109/419]

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

Definition at line 2115 of file aiks_unittests.cc.

2115  {
2116  Canvas canvas;
2117  canvas.SaveLayer({}, std::nullopt,
2118  ImageFilter::MakeBlur(Sigma(3), Sigma(3),
2119  FilterContents::BlurStyle::kNormal,
2120  Entity::TileMode::kClamp));
2121  canvas.DrawPaint({.color = Color::Red(), .blend_mode = BlendMode::kSource});
2122  canvas.DrawPaint({.color = Color::CornflowerBlue().WithAlpha(0.75),
2123  .blend_mode = BlendMode::kSourceOver});
2124  canvas.Restore();
2125 
2126  Picture picture = canvas.EndRecordingAsPicture();
2127 
2128  std::optional<Color> actual_color;
2129  bool found_subpass = false;
2130  picture.pass->IterateAllElements([&](EntityPass::Element& element) -> bool {
2131  if (auto subpass = std::get_if<std::unique_ptr<EntityPass>>(&element)) {
2132  actual_color = subpass->get()->GetClearColor();
2133  found_subpass = true;
2134  }
2135  // Fail if the first element isn't a subpass.
2136  return true;
2137  });
2138 
2139  EXPECT_TRUE(found_subpass);
2140  EXPECT_FALSE(actual_color.has_value());
2141 }

References impeller::Color::CornflowerBlue(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kClamp, impeller::FilterContents::kNormal, impeller::kSource, impeller::kSourceOver, impeller::ImageFilter::MakeBlur(), impeller::Picture::pass, impeller::Color::Red(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Color::WithAlpha().

◆ TEST_P() [110/419]

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

Definition at line 3225 of file aiks_unittests.cc.

3225  {
3226  SetWindowSize({400, 400});
3227  Canvas canvas;
3228  canvas.Scale(GetContentScale());
3229  canvas.DrawRect(Rect::MakeLTRB(200, 200, 300, 300), {.color = Color::Red()});
3230  canvas.SaveLayer({
3231  .image_filter = std::make_shared<MatrixImageFilter>(
3232  Matrix::MakeScale({2, 2, 1}), SamplerDescriptor{}),
3233  });
3234  // Draw a rectangle that would fully cover the parent pass size, but not
3235  // the subpass that it is rendered in.
3236  canvas.DrawRect(Rect::MakeLTRB(0, 0, 400, 400), {.color = Color::Green()});
3237  // Draw a bigger rectangle to force the subpass to be bigger.
3238  canvas.DrawRect(Rect::MakeLTRB(0, 0, 800, 800), {.color = Color::Red()});
3239  canvas.Restore();
3240 
3241  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3242 }

References impeller::Color::Green(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeScale(), impeller::Color::Red(), and impeller::Canvas::Scale().

◆ TEST_P() [111/419]

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

Definition at line 168 of file aiks_blur_unittests.cc.

168  {
169  Canvas canvas;
170  canvas.Translate(Point(0, -400));
171  Paint paint;
172  paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
173  .style = FilterContents::BlurStyle::kNormal,
174  .sigma = Radius{120 * 3},
175  };
176  paint.color = Color::Red();
177  PathBuilder builder{};
178  builder.AddRect(Rect::MakeLTRB(0, 0, 800, 800));
179  canvas.DrawPath(builder.TakePath(), paint);
180  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
181 }

References impeller::PathBuilder::AddRect(), impeller::Paint::color, impeller::Canvas::DrawPath(), impeller::Canvas::EndRecordingAsPicture(), impeller::FilterContents::kNormal, impeller::TRect< Scalar >::MakeLTRB(), impeller::Paint::mask_blur_descriptor, impeller::Color::Red(), impeller::Paint::MaskBlurDescriptor::style, and impeller::Canvas::Translate().

◆ TEST_P() [112/419]

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

Definition at line 146 of file aiks_blur_unittests.cc.

146  {
147  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
148  static PlaygroundPoint playground_point(Point(400, 400), 20,
149  Color::Green());
150  auto point = DrawPlaygroundPoint(playground_point);
151 
152  Canvas canvas;
153  canvas.Translate(point - Point(400, 400));
154  Paint paint;
155  paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
156  .style = FilterContents::BlurStyle::kNormal,
157  .sigma = Radius{120 * 3},
158  };
159  paint.color = Color::Red();
160  PathBuilder builder{};
161  builder.AddRect(Rect::MakeLTRB(0, 0, 800, 800));
162  canvas.DrawPath(builder.TakePath(), paint);
163  return canvas.EndRecordingAsPicture();
164  };
165  ASSERT_TRUE(OpenPlaygroundHere(callback));
166 }

References impeller::PathBuilder::AddRect(), impeller::Paint::color, impeller::Canvas::DrawPath(), impeller::DrawPlaygroundPoint(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::FilterContents::kNormal, impeller::TRect< Scalar >::MakeLTRB(), impeller::Paint::mask_blur_descriptor, impeller::Color::Red(), impeller::Paint::MaskBlurDescriptor::style, and impeller::Canvas::Translate().

◆ TEST_P() [113/419]

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

Definition at line 2091 of file aiks_unittests.cc.

2091  {
2092  Canvas canvas(Rect::MakeXYWH(0, 0, 100, 100));
2093  canvas.ClipRect(Rect::MakeXYWH(0, 0, 100, 100));
2094  canvas.ClipRect(Rect::MakeXYWH(-100, -100, 300, 300));
2095  canvas.DrawPaint({.color = Color::Red(), .blend_mode = BlendMode::kSource});
2096  canvas.DrawPaint({.color = Color::CornflowerBlue().WithAlpha(0.75),
2097  .blend_mode = BlendMode::kSourceOver});
2098 
2099  Picture picture = canvas.EndRecordingAsPicture();
2100  auto expected = Color::Red().Blend(Color::CornflowerBlue().WithAlpha(0.75),
2101  BlendMode::kSourceOver);
2102  ASSERT_EQ(picture.pass->GetClearColor(), expected);
2103 
2104  std::shared_ptr<ContextSpy> spy = ContextSpy::Make();
2105  std::shared_ptr<Context> real_context = GetContext();
2106  std::shared_ptr<ContextMock> mock_context = spy->MakeContext(real_context);
2107  AiksContext renderer(mock_context, nullptr);
2108  std::shared_ptr<Image> image = picture.ToImage(renderer, {300, 300});
2109 
2110  ASSERT_EQ(spy->render_passes_.size(), 1llu);
2111  std::shared_ptr<RenderPass> render_pass = spy->render_passes_[0];
2112  ASSERT_EQ(render_pass->GetCommands().size(), 0llu);
2113 }

References impeller::Color::Blend(), impeller::Canvas::ClipRect(), impeller::Color::CornflowerBlue(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::kSource, impeller::kSourceOver, impeller::TRect< Scalar >::MakeXYWH(), impeller::Picture::pass, impeller::Color::Red(), impeller::Picture::ToImage(), and impeller::Color::WithAlpha().

◆ TEST_P() [114/419]

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

Definition at line 412 of file aiks_unittests.cc.

412  {
413  std::array<Color, 5> colors = {Color::White(), Color::Black(),
414  Color::SkyBlue(), Color::Red(),
415  Color::Yellow()};
416  Canvas canvas;
417  Paint paint;
418 
419  canvas.Translate(Vector3(300, 300));
420  for (int i = 0; i < 15; i++) {
421  canvas.Scale(Vector3(0.8, 0.8));
422 
423  paint.color = colors[i % colors.size()];
424  canvas.ClipPath(PathBuilder{}.AddCircle({0, 0}, 300).TakePath());
425  canvas.DrawRect(Rect::MakeXYWH(-300, -300, 600, 600), paint);
426  }
427  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
428 }

References impeller::PathBuilder::AddCircle(), impeller::Color::Black(), impeller::Canvas::ClipPath(), impeller::Paint::color, impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Color::Red(), impeller::Canvas::Scale(), impeller::Color::SkyBlue(), impeller::Canvas::Translate(), impeller::Color::White(), and impeller::Color::Yellow().

◆ TEST_P() [115/419]

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

Definition at line 2143 of file aiks_unittests.cc.

2143  {
2144  Canvas canvas;
2145  canvas.DrawPaint(
2146  {.color = Color::Yellow(), .blend_mode = BlendMode::kSource});
2147  canvas.SaveLayer({.blend_mode = BlendMode::kMultiply});
2148  canvas.DrawPaint({.color = Color::CornflowerBlue().WithAlpha(0.75),
2149  .blend_mode = BlendMode::kSourceOver});
2150 
2151  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2152 }

References impeller::Color::CornflowerBlue(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::kMultiply, impeller::kSource, impeller::kSourceOver, impeller::Canvas::SaveLayer(), impeller::Color::WithAlpha(), and impeller::Color::Yellow().

◆ TEST_P() [116/419]

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

Definition at line 2154 of file aiks_unittests.cc.

2154  {
2155  // Bug: https://github.com/flutter/flutter/issues/131576
2156  Canvas canvas;
2157  canvas.DrawPaint(
2158  {.color = Color::Yellow(), .blend_mode = BlendMode::kSource});
2159  canvas.SaveLayer({}, {},
2160  ImageFilter::MakeBlur(Sigma(20.0), Sigma(20.0),
2161  FilterContents::BlurStyle::kNormal,
2162  Entity::TileMode::kDecal));
2163  canvas.DrawPaint(
2164  {.color = Color::CornflowerBlue(), .blend_mode = BlendMode::kSourceOver});
2165 
2166  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2167 }

References impeller::Color::CornflowerBlue(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kDecal, impeller::FilterContents::kNormal, impeller::kSource, impeller::kSourceOver, impeller::ImageFilter::MakeBlur(), impeller::Canvas::SaveLayer(), and impeller::Color::Yellow().

◆ TEST_P() [117/419]

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

Definition at line 2184 of file aiks_unittests.cc.

2184  {
2185  Canvas canvas;
2186 
2187  canvas.SaveLayer({
2188  .color_filter =
2189  ColorFilter::MakeMatrix({.array =
2190  {
2191  -1.0, 0, 0, 1.0, 0, //
2192  0, -1.0, 0, 1.0, 0, //
2193  0, 0, -1.0, 1.0, 0, //
2194  1.0, 1.0, 1.0, 1.0, 0 //
2195  }}),
2196  });
2197 
2198  canvas.Translate({500, 300, 0});
2199  canvas.Rotate(Radians(2 * kPi / 3));
2200  canvas.DrawRect(Rect::MakeXYWH(100, 100, 200, 200), {.color = Color::Blue()});
2201 
2202  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2203 }

References impeller::Color::Blue(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::kPi, impeller::ColorFilter::MakeMatrix(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Canvas::Rotate(), impeller::Canvas::SaveLayer(), and impeller::Canvas::Translate().

◆ TEST_P() [118/419]

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

1105  {
1106  // Compare with https://fiddle.skia.org/c/@BlendModes
1107 
1108  BlendModeSelection blend_modes = GetBlendModeSelection();
1109 
1110  auto draw_color_wheel = [](Canvas& canvas) {
1111  /// color_wheel_sampler: r=0 -> fuchsia, r=2pi/3 -> yellow, r=4pi/3 ->
1112  /// cyan domain: r >= 0 (because modulo used is non euclidean)
1113  auto color_wheel_sampler = [](Radians r) {
1114  Scalar x = r.radians / k2Pi + 1;
1115 
1116  // https://www.desmos.com/calculator/6nhjelyoaj
1117  auto color_cycle = [](Scalar x) {
1118  Scalar cycle = std::fmod(x, 6.0f);
1119  return std::max(0.0f, std::min(1.0f, 2 - std::abs(2 - cycle)));
1120  };
1121  return Color(color_cycle(6 * x + 1), //
1122  color_cycle(6 * x - 1), //
1123  color_cycle(6 * x - 3), //
1124  1);
1125  };
1126 
1127  Paint paint;
1128  paint.blend_mode = BlendMode::kSourceOver;
1129 
1130  // Draw a fancy color wheel for the backdrop.
1131  // https://www.desmos.com/calculator/xw7kafthwd
1132  const int max_dist = 900;
1133  for (int i = 0; i <= 900; i++) {
1134  Radians r(kPhi / k2Pi * i);
1135  Scalar distance = r.radians / std::powf(4.12, 0.0026 * r.radians);
1136  Scalar normalized_distance = static_cast<Scalar>(i) / max_dist;
1137 
1138  paint.color =
1139  color_wheel_sampler(r).WithAlpha(1.0f - normalized_distance);
1140  Point position(distance * std::sin(r.radians),
1141  -distance * std::cos(r.radians));
1142 
1143  canvas.DrawCircle(position, 9 + normalized_distance * 3, paint);
1144  }
1145  };
1146 
1147  std::shared_ptr<Image> color_wheel_image;
1148  Matrix color_wheel_transform;
1149 
1150  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
1151  // UI state.
1152  static bool cache_the_wheel = true;
1153  static int current_blend_index = 3;
1154  static float dst_alpha = 1;
1155  static float src_alpha = 1;
1156  static Color color0 = Color::Red();
1157  static Color color1 = Color::Green();
1158  static Color color2 = Color::Blue();
1159 
1160  if (AiksTest::ImGuiBegin("Controls", nullptr,
1161  ImGuiWindowFlags_AlwaysAutoResize)) {
1162  ImGui::Checkbox("Cache the wheel", &cache_the_wheel);
1163  ImGui::ListBox("Blending mode", &current_blend_index,
1164  blend_modes.blend_mode_names.data(),
1165  blend_modes.blend_mode_names.size());
1166  ImGui::SliderFloat("Source alpha", &src_alpha, 0, 1);
1167  ImGui::ColorEdit4("Color A", reinterpret_cast<float*>(&color0));
1168  ImGui::ColorEdit4("Color B", reinterpret_cast<float*>(&color1));
1169  ImGui::ColorEdit4("Color C", reinterpret_cast<float*>(&color2));
1170  ImGui::SliderFloat("Destination alpha", &dst_alpha, 0, 1);
1171  ImGui::End();
1172  }
1173 
1174  static Point content_scale;
1175  Point new_content_scale = GetContentScale();
1176 
1177  if (!cache_the_wheel || new_content_scale != content_scale) {
1178  content_scale = new_content_scale;
1179 
1180  // Render the color wheel to an image.
1181 
1182  Canvas canvas;
1183  canvas.Scale(content_scale);
1184 
1185  canvas.Translate(Vector2(500, 400));
1186  canvas.Scale(Vector2(3, 3));
1187 
1188  draw_color_wheel(canvas);
1189  auto color_wheel_picture = canvas.EndRecordingAsPicture();
1190  auto snapshot = color_wheel_picture.Snapshot(renderer);
1191  if (!snapshot.has_value() || !snapshot->texture) {
1192  return std::nullopt;
1193  }
1194  color_wheel_image = std::make_shared<Image>(snapshot->texture);
1195  color_wheel_transform = snapshot->transform;
1196  }
1197 
1198  Canvas canvas;
1199 
1200  // Blit the color wheel backdrop to the screen with managed alpha.
1201  canvas.SaveLayer({.color = Color::White().WithAlpha(dst_alpha),
1202  .blend_mode = BlendMode::kSource});
1203  {
1204  canvas.DrawPaint({.color = Color::White()});
1205 
1206  canvas.Save();
1207  canvas.Transform(color_wheel_transform);
1208  canvas.DrawImage(color_wheel_image, Point(), Paint());
1209  canvas.Restore();
1210  }
1211  canvas.Restore();
1212 
1213  canvas.Scale(content_scale);
1214  canvas.Translate(Vector2(500, 400));
1215  canvas.Scale(Vector2(3, 3));
1216 
1217  // Draw 3 circles to a subpass and blend it in.
1218  canvas.SaveLayer(
1219  {.color = Color::White().WithAlpha(src_alpha),
1220  .blend_mode = blend_modes.blend_mode_values[current_blend_index]});
1221  {
1222  Paint paint;
1223  paint.blend_mode = BlendMode::kPlus;
1224  const Scalar x = std::sin(k2Pi / 3);
1225  const Scalar y = -std::cos(k2Pi / 3);
1226  paint.color = color0;
1227  canvas.DrawCircle(Point(-x, y) * 45, 65, paint);
1228  paint.color = color1;
1229  canvas.DrawCircle(Point(0, -1) * 45, 65, paint);
1230  paint.color = color2;
1231  canvas.DrawCircle(Point(x, y) * 45, 65, paint);
1232  }
1233  canvas.Restore();
1234 
1235  return canvas.EndRecordingAsPicture();
1236  };
1237 
1238  ASSERT_TRUE(OpenPlaygroundHere(callback));
1239 }

References impeller::Paint::blend_mode, impeller::testing::BlendModeSelection::blend_mode_names, impeller::testing::BlendModeSelection::blend_mode_values, impeller::Color::Blue(), impeller::Paint::color, impeller::saturated::distance, impeller::Canvas::DrawCircle(), impeller::Canvas::DrawImage(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), GetBlendModeSelection(), impeller::Color::Green(), impeller::AiksPlayground::ImGuiBegin(), impeller::k2Pi, impeller::kPhi, impeller::kPlus, impeller::kSource, impeller::kSourceOver, impeller::Radians::radians, impeller::Color::Red(), impeller::Canvas::Restore(), impeller::Canvas::Save(), impeller::Canvas::SaveLayer(), impeller::Canvas::Scale(), impeller::Picture::Snapshot(), impeller::Canvas::Transform(), impeller::Canvas::Translate(), impeller::Color::White(), and impeller::Color::WithAlpha().

◆ TEST_P() [119/419]

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

Definition at line 569 of file aiks_unittests.cc.

569  {
570  Canvas canvas;
571 
572  // Render a texture directly.
573  {
574  Paint paint;
575  auto image =
576  std::make_shared<Image>(CreateTextureForFixture("kalimba.jpg"));
577  paint.color = Color::Red();
578 
579  canvas.Save();
580  canvas.Translate({100, 200, 0});
581  canvas.Scale(Vector2{0.5, 0.5});
582  canvas.DrawImage(image, Point::MakeXY(100.0, 100.0), paint);
583  canvas.Restore();
584  }
585 
586  // Render an offscreen rendered texture.
587  {
588  Paint red;
589  red.color = Color::Red();
590  Paint green;
591  green.color = Color::Green();
592  Paint blue;
593  blue.color = Color::Blue();
594 
595  Paint alpha;
596  alpha.color = Color::Red().WithAlpha(0.5);
597 
598  canvas.SaveLayer(alpha);
599 
600  canvas.DrawRect(Rect::MakeXYWH(000, 000, 100, 100), red);
601  canvas.DrawRect(Rect::MakeXYWH(020, 020, 100, 100), green);
602  canvas.DrawRect(Rect::MakeXYWH(040, 040, 100, 100), blue);
603 
604  canvas.Restore();
605  }
606 
607  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
608 }

References impeller::Color::Blue(), impeller::Paint::color, impeller::Canvas::DrawImage(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::TPoint< Scalar >::MakeXY(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Color::Red(), impeller::Canvas::Restore(), impeller::Canvas::Save(), impeller::Canvas::SaveLayer(), impeller::Canvas::Scale(), impeller::Canvas::Translate(), and impeller::Color::WithAlpha().

◆ TEST_P() [120/419]

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

Definition at line 3334 of file aiks_unittests.cc.

3334  {
3335  Canvas canvas; // Depth 1 (base pass)
3336  canvas.DrawRRect(Rect::MakeLTRB(0, 0, 100, 100), {10, 10}, {}); // Depth 2
3337  canvas.Save();
3338  {
3339  canvas.ClipRRect(Rect::MakeLTRB(0, 0, 50, 50), {10, 10}, {}); // Depth 4
3340  canvas.SaveLayer({}); // Depth 4
3341  {
3342  canvas.DrawRRect(Rect::MakeLTRB(0, 0, 50, 50), {10, 10}, {}); // Depth 3
3343  }
3344  canvas.Restore(); // Restore the savelayer.
3345  }
3346  canvas.Restore(); // Depth 5 -- this will no longer append a restore entity
3347  // once we switch to the clip depth approach.
3348 
3349  auto picture = canvas.EndRecordingAsPicture();
3350 
3351  std::vector<uint32_t> expected = {
3352  2, // DrawRRect
3353  4, // ClipRRect -- Has a depth value equal to the max depth of all the
3354  // content it affect. In this case, the SaveLayer and all
3355  // its contents are affected.
3356  4, // SaveLayer -- The SaveLayer is drawn to the parent pass after its
3357  // contents are rendered, so it should have a depth value
3358  // greater than all its contents.
3359  3, // DrawRRect
3360  5, // Restore (no longer necessary when clipping on the depth buffer)
3361  };
3362 
3363  std::vector<uint32_t> actual;
3364 
3365  picture.pass->IterateAllElements([&](EntityPass::Element& element) -> bool {
3366  if (auto* subpass = std::get_if<std::unique_ptr<EntityPass>>(&element)) {
3367  actual.push_back(subpass->get()->GetNewClipDepth());
3368  }
3369  if (Entity* entity = std::get_if<Entity>(&element)) {
3370  actual.push_back(entity->GetNewClipDepth());
3371  }
3372  return true;
3373  });
3374 
3375  ASSERT_EQ(actual.size(), expected.size());
3376  for (size_t i = 0; i < expected.size(); i++) {
3377  EXPECT_EQ(expected[i], actual[i]) << "Index: " << i;
3378  }
3379 }

References impeller::Canvas::ClipRRect(), impeller::Canvas::DrawRRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Picture::pass, impeller::Canvas::Restore(), impeller::Canvas::Save(), and impeller::Canvas::SaveLayer().

◆ TEST_P() [121/419]

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

Definition at line 1708 of file aiks_unittests.cc.

1708  {
1709  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
1710  Canvas canvas;
1711  canvas.Scale(GetContentScale());
1712 
1713  Paint alpha;
1714  alpha.color = Color::Red().WithAlpha(0.5);
1715 
1716  auto current = Point{25, 25};
1717  const auto offset = Point{25, 25};
1718  const auto size = Size(100, 100);
1719 
1720  static PlaygroundPoint point_a(Point(40, 40), 10, Color::White());
1721  static PlaygroundPoint point_b(Point(160, 160), 10, Color::White());
1722  auto [b0, b1] = DrawPlaygroundLine(point_a, point_b);
1723  auto bounds = Rect::MakeLTRB(b0.x, b0.y, b1.x, b1.y);
1724 
1725  canvas.DrawRect(bounds, Paint{.color = Color::Yellow(),
1726  .stroke_width = 5.0f,
1727  .style = Paint::Style::kStroke});
1728 
1729  canvas.SaveLayer(alpha, bounds);
1730 
1731  canvas.DrawRect(Rect::MakeOriginSize(current, size),
1732  Paint{.color = Color::Red()});
1733  canvas.DrawRect(Rect::MakeOriginSize(current += offset, size),
1734  Paint{.color = Color::Green()});
1735  canvas.DrawRect(Rect::MakeOriginSize(current += offset, size),
1736  Paint{.color = Color::Blue()});
1737 
1738  canvas.Restore();
1739 
1740  return canvas.EndRecordingAsPicture();
1741  };
1742 
1743  ASSERT_TRUE(OpenPlaygroundHere(callback));
1744 }

References impeller::Color::Blue(), impeller::Paint::color, impeller::DrawPlaygroundLine(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::Paint::kStroke, impeller::TRect< Scalar >::MakeLTRB(), impeller::TRect< Scalar >::MakeOriginSize(), offset, impeller::Color::Red(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), impeller::Canvas::Scale(), impeller::Color::White(), impeller::Color::WithAlpha(), and impeller::Color::Yellow().

◆ TEST_P() [122/419]

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

Definition at line 1013 of file aiks_unittests.cc.

1013  {
1014  std::vector<Color> colors = {Color{0.9568, 0.2627, 0.2118, 1.0},
1015  Color{0.1294, 0.5882, 0.9529, 1.0}};
1016  std::vector<Scalar> stops = {0.0, 1.0};
1017 
1018  Paint paint = {
1019  .color_source = ColorSource::MakeLinearGradient(
1020  {0, 0}, {100, 100}, std::move(colors), std::move(stops),
1021  Entity::TileMode::kRepeat, Matrix::MakeScale(Vector3(0.3, 0.3, 0.3))),
1022  .blend_mode = BlendMode::kLighten,
1023  };
1024 
1025  Canvas canvas;
1026  canvas.DrawPaint({.color = Color::Blue()});
1027  canvas.Scale(Vector2(2, 2));
1028  canvas.ClipRect(Rect::MakeLTRB(0, 0, 200, 200));
1029  canvas.DrawCircle({100, 100}, 100, paint);
1030  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1031 }

References impeller::Color::Blue(), impeller::Canvas::ClipRect(), impeller::Paint::color_source, impeller::Canvas::DrawCircle(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::kLighten, impeller::Entity::kRepeat, impeller::ColorSource::MakeLinearGradient(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeScale(), and impeller::Canvas::Scale().

◆ TEST_P() [123/419]

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

Definition at line 2840 of file aiks_unittests.cc.

2840  {
2841  // Draws the image as four squares stiched together.
2842  auto atlas = CreateTextureForFixture("bay_bridge.jpg");
2843  auto size = atlas->GetSize();
2844  auto image = std::make_shared<Image>(atlas);
2845  // Divide image into four quadrants.
2846  Scalar half_width = size.width / 2;
2847  Scalar half_height = size.height / 2;
2848  std::vector<Rect> texture_coordinates = {
2849  Rect::MakeLTRB(0, 0, half_width, half_height),
2850  Rect::MakeLTRB(half_width, 0, size.width, half_height),
2851  Rect::MakeLTRB(0, half_height, half_width, size.height),
2852  Rect::MakeLTRB(half_width, half_height, size.width, size.height)};
2853  // Position quadrants adjacent to eachother.
2854  std::vector<Matrix> transforms = {
2855  Matrix::MakeTranslation({0, 0, 0}),
2856  Matrix::MakeTranslation({half_width, 0, 0}),
2857  Matrix::MakeTranslation({0, half_height, 0}),
2858  Matrix::MakeTranslation({half_width, half_height, 0})};
2859 
2860  Paint paint;
2861 
2862  Canvas canvas;
2863  canvas.Scale({0.25, 0.25, 1.0});
2864  canvas.DrawAtlas(image, transforms, texture_coordinates, {},
2865  BlendMode::kModulate, {}, std::nullopt, paint);
2866 
2867  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2868 }

References impeller::Canvas::DrawAtlas(), impeller::Canvas::EndRecordingAsPicture(), impeller::kModulate, impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeTranslation(), and impeller::Canvas::Scale().

◆ TEST_P() [124/419]

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

Definition at line 2807 of file aiks_unittests.cc.

2807  {
2808  // Draws the image as four squares stiched together.
2809  auto atlas = CreateTextureForFixture("bay_bridge.jpg");
2810  auto size = atlas->GetSize();
2811  auto image = std::make_shared<Image>(atlas);
2812  // Divide image into four quadrants.
2813  Scalar half_width = size.width / 2;
2814  Scalar half_height = size.height / 2;
2815  std::vector<Rect> texture_coordinates = {
2816  Rect::MakeLTRB(0, 0, half_width, half_height),
2817  Rect::MakeLTRB(half_width, 0, size.width, half_height),
2818  Rect::MakeLTRB(0, half_height, half_width, size.height),
2819  Rect::MakeLTRB(half_width, half_height, size.width, size.height)};
2820  // Position quadrants adjacent to eachother.
2821  std::vector<Matrix> transforms = {
2822  Matrix::MakeTranslation({0, 0, 0}),
2823  Matrix::MakeTranslation({half_width, 0, 0}),
2824  Matrix::MakeTranslation({0, half_height, 0}),
2825  Matrix::MakeTranslation({half_width, half_height, 0})};
2826  std::vector<Color> colors = {Color::Red(), Color::Green(), Color::Blue(),
2827  Color::Yellow()};
2828 
2829  Paint paint;
2830 
2831  Canvas canvas;
2832  canvas.Scale({0.25, 0.25, 1.0});
2833  canvas.DrawAtlas(image, transforms, texture_coordinates, colors,
2834  BlendMode::kModulate, {}, std::nullopt, paint);
2835 
2836  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2837 }

References impeller::Color::Blue(), impeller::Canvas::DrawAtlas(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::kModulate, impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeTranslation(), impeller::Color::Red(), impeller::Canvas::Scale(), and impeller::Color::Yellow().

◆ TEST_P() [125/419]

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

Definition at line 250 of file aiks_path_unittests.cc.

250  {
251  Canvas canvas;
252  canvas.Scale(GetContentScale());
253  Paint paint;
254  paint.color = Color::Blue();
255  paint.stroke_width = 10;
256 
257  auto draw = [&canvas](Paint& paint) {
258  for (auto cap : {Cap::kButt, Cap::kSquare, Cap::kRound}) {
259  paint.stroke_cap = cap;
260  Point origin = {100, 100};
261  Point p0 = {50, 0};
262  Point p1 = {150, 0};
263  canvas.DrawLine({150, 100}, {250, 100}, paint);
264  for (int d = 15; d < 90; d += 15) {
265  Matrix m = Matrix::MakeRotationZ(Degrees(d));
266  canvas.DrawLine(origin + m * p0, origin + m * p1, paint);
267  }
268  canvas.DrawLine({100, 150}, {100, 250}, paint);
269  canvas.DrawCircle({origin}, 35, paint);
270 
271  canvas.DrawLine({250, 250}, {250, 250}, paint);
272 
273  canvas.Translate({250, 0});
274  }
275  canvas.Translate({-750, 250});
276  };
277 
278  std::vector<Color> colors = {
279  Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0},
280  Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0},
281  Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0},
282  Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0},
283  Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0},
284  Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0},
285  Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}};
286  std::vector<Scalar> stops = {
287  0.0,
288  (1.0 / 6.0) * 1,
289  (1.0 / 6.0) * 2,
290  (1.0 / 6.0) * 3,
291  (1.0 / 6.0) * 4,
292  (1.0 / 6.0) * 5,
293  1.0,
294  };
295 
296  auto texture = CreateTextureForFixture("airplane.jpg",
297  /*enable_mipmapping=*/true);
298 
299  draw(paint);
300 
301  paint.color_source = ColorSource::MakeRadialGradient(
302  {100, 100}, 200, std::move(colors), std::move(stops),
303  Entity::TileMode::kMirror, {});
304  draw(paint);
305 
306  paint.color_source = ColorSource::MakeImage(
307  texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {},
308  Matrix::MakeTranslation({-150, 75}));
309  draw(paint);
310 
311  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
312 }

References impeller::Color::Blue(), impeller::Paint::color, impeller::Paint::color_source, impeller::Canvas::DrawCircle(), impeller::Canvas::DrawLine(), impeller::Canvas::EndRecordingAsPicture(), impeller::kButt, impeller::Entity::kMirror, impeller::Entity::kRepeat, impeller::kRound, impeller::kSquare, impeller::ColorSource::MakeImage(), impeller::ColorSource::MakeRadialGradient(), impeller::Matrix::MakeRotationZ(), impeller::Matrix::MakeTranslation(), impeller::Canvas::Scale(), impeller::Paint::stroke_cap, impeller::Paint::stroke_width, and impeller::Canvas::Translate().

◆ TEST_P() [126/419]

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

Definition at line 1964 of file aiks_unittests.cc.

1964  {
1965  Canvas canvas;
1966  canvas.DrawPaint({.color = Color::Red(), .blend_mode = BlendMode::kSource});
1967  canvas.DrawPaint({.color = Color::CornflowerBlue().WithAlpha(0.75),
1968  .blend_mode = BlendMode::kSourceOver});
1969 
1970  Picture picture = canvas.EndRecordingAsPicture();
1971  auto expected = Color::Red().Blend(Color::CornflowerBlue().WithAlpha(0.75),
1972  BlendMode::kSourceOver);
1973  ASSERT_EQ(picture.pass->GetClearColor(), expected);
1974 
1975  std::shared_ptr<ContextSpy> spy = ContextSpy::Make();
1976  std::shared_ptr<Context> real_context = GetContext();
1977  std::shared_ptr<ContextMock> mock_context = spy->MakeContext(real_context);
1978  AiksContext renderer(mock_context, nullptr);
1979  std::shared_ptr<Image> image = picture.ToImage(renderer, {300, 300});
1980 
1981  ASSERT_EQ(spy->render_passes_.size(), 1llu);
1982  std::shared_ptr<RenderPass> render_pass = spy->render_passes_[0];
1983  ASSERT_EQ(render_pass->GetCommands().size(), 0llu);
1984 }

References impeller::Color::Blend(), impeller::Color::CornflowerBlue(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::kSource, impeller::kSourceOver, impeller::Picture::pass, impeller::Color::Red(), impeller::Picture::ToImage(), and impeller::Color::WithAlpha().

◆ TEST_P() [127/419]

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

Definition at line 2747 of file aiks_unittests.cc.

2747  {
2748  auto runtime_stages = OpenAssetAsRuntimeStage("gradient.frag.iplr");
2749  auto runtime_stage =
2750  runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
2751  ASSERT_TRUE(runtime_stage);
2752  ASSERT_TRUE(runtime_stage->IsDirty());
2753 
2754  struct FragUniforms {
2755  Size size;
2756  } frag_uniforms = {.size = Size::MakeWH(400, 400)};
2757  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
2758  uniform_data->resize(sizeof(FragUniforms));
2759  memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
2760 
2761  std::vector<RuntimeEffectContents::TextureInput> texture_inputs;
2762 
2763  Paint paint;
2764  paint.color_source = ColorSource::MakeRuntimeEffect(
2765  runtime_stage, uniform_data, texture_inputs);
2766 
2767  Canvas canvas;
2768  canvas.Save();
2769  canvas.Scale(GetContentScale());
2770  canvas.DrawPaint(paint);
2771  canvas.Restore();
2772 
2773  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2774 }

References impeller::Paint::color_source, impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::ColorSource::MakeRuntimeEffect(), impeller::TSize< Scalar >::MakeWH(), impeller::PlaygroundBackendToRuntimeStageBackend(), impeller::Canvas::Restore(), impeller::Canvas::Save(), and impeller::Canvas::Scale().

◆ TEST_P() [128/419]

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

Definition at line 996 of file aiks_unittests.cc.

996  {
997  Paint filtered = {
998  .color = Color::Black(),
999  .mask_blur_descriptor =
1000  Paint::MaskBlurDescriptor{
1001  .style = FilterContents::BlurStyle::kNormal,
1002  .sigma = Sigma(60),
1003  },
1004  };
1005 
1006  Canvas canvas;
1007  canvas.DrawPaint({.color = Color::White()});
1008  canvas.DrawCircle({300, 300}, 200, filtered);
1009  canvas.DrawPaint({.color = Color::Green(), .blend_mode = BlendMode::kScreen});
1010  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1011 }

References impeller::Color::Black(), impeller::Paint::color, impeller::Canvas::DrawCircle(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::FilterContents::kNormal, impeller::kScreen, impeller::Paint::MaskBlurDescriptor::style, and impeller::Color::White().

◆ TEST_P() [129/419]

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

Definition at line 2011 of file aiks_unittests.cc.

2011  {
2012  Canvas canvas;
2013  canvas.DrawRect(Rect::MakeXYWH(0, 0, 300, 300),
2014  {.color = Color::Red(), .blend_mode = BlendMode::kSource});
2015  canvas.DrawRect(Rect::MakeXYWH(0, 0, 300, 300),
2016  {.color = Color::CornflowerBlue().WithAlpha(0.75),
2017  .blend_mode = BlendMode::kSourceOver});
2018 
2019  std::shared_ptr<ContextSpy> spy = ContextSpy::Make();
2020  Picture picture = canvas.EndRecordingAsPicture();
2021  std::shared_ptr<Context> real_context = GetContext();
2022  std::shared_ptr<ContextMock> mock_context = spy->MakeContext(real_context);
2023  AiksContext renderer(mock_context, nullptr);
2024  std::shared_ptr<Image> image = picture.ToImage(renderer, {300, 300});
2025 
2026  ASSERT_EQ(spy->render_passes_.size(), 1llu);
2027  std::shared_ptr<RenderPass> render_pass = spy->render_passes_[0];
2028  ASSERT_EQ(render_pass->GetCommands().size(), 0llu);
2029 }

References impeller::Color::CornflowerBlue(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::kSource, impeller::kSourceOver, impeller::TRect< Scalar >::MakeXYWH(), impeller::Color::Red(), impeller::Picture::ToImage(), and impeller::Color::WithAlpha().

◆ TEST_P() [130/419]

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

Definition at line 2071 of file aiks_unittests.cc.

2071  {
2072  Canvas canvas;
2073  canvas.DrawRect(Rect::MakeXYWH(0, 0, 300, 300),
2074  {.color = Color::Red(), .blend_mode = BlendMode::kSource});
2075  canvas.DrawRect(Rect::MakeXYWH(0, 0, 300, 300),
2076  {.color = Color::CornflowerBlue().WithAlpha(0.75),
2077  .blend_mode = BlendMode::kSourceOver});
2078 
2079  std::shared_ptr<ContextSpy> spy = ContextSpy::Make();
2080  Picture picture = canvas.EndRecordingAsPicture();
2081  std::shared_ptr<Context> real_context = GetContext();
2082  std::shared_ptr<ContextMock> mock_context = spy->MakeContext(real_context);
2083  AiksContext renderer(mock_context, nullptr);
2084  std::shared_ptr<Image> image = picture.ToImage(renderer, {301, 301});
2085 
2086  ASSERT_EQ(spy->render_passes_.size(), 1llu);
2087  std::shared_ptr<RenderPass> render_pass = spy->render_passes_[0];
2088  ASSERT_EQ(render_pass->GetCommands().size(), 2llu);
2089 }

References impeller::Color::CornflowerBlue(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::kSource, impeller::kSourceOver, impeller::TRect< Scalar >::MakeXYWH(), impeller::Color::Red(), impeller::Picture::ToImage(), and impeller::Color::WithAlpha().

◆ TEST_P() [131/419]

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

Definition at line 2051 of file aiks_unittests.cc.

2051  {
2052  Canvas canvas;
2053  canvas.Translate(Vector3(150.0, 150.0, 0.0));
2054  canvas.Rotate(Degrees(45.0));
2055  canvas.Translate(Vector3(-150.0, -150.0, 0.0));
2056  canvas.DrawRect(Rect::MakeXYWH(0, 0, 300, 300),
2057  {.color = Color::Red(), .blend_mode = BlendMode::kSource});
2058 
2059  std::shared_ptr<ContextSpy> spy = ContextSpy::Make();
2060  Picture picture = canvas.EndRecordingAsPicture();
2061  std::shared_ptr<Context> real_context = GetContext();
2062  std::shared_ptr<ContextMock> mock_context = spy->MakeContext(real_context);
2063  AiksContext renderer(mock_context, nullptr);
2064  std::shared_ptr<Image> image = picture.ToImage(renderer, {300, 300});
2065 
2066  ASSERT_EQ(spy->render_passes_.size(), 1llu);
2067  std::shared_ptr<RenderPass> render_pass = spy->render_passes_[0];
2068  ASSERT_EQ(render_pass->GetCommands().size(), 1llu);
2069 }

References impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::kSource, impeller::TRect< Scalar >::MakeXYWH(), impeller::Color::Red(), impeller::Canvas::Rotate(), impeller::Picture::ToImage(), and impeller::Canvas::Translate().

◆ TEST_P() [132/419]

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

Definition at line 2031 of file aiks_unittests.cc.

2031  {
2032  Canvas canvas;
2033  canvas.DrawRRect(Rect::MakeXYWH(0, 0, 300, 300), {5.0, 5.0},
2034  {.color = Color::Red(), .blend_mode = BlendMode::kSource});
2035  canvas.DrawRRect(Rect::MakeXYWH(0, 0, 300, 300), {5.0, 5.0},
2036  {.color = Color::CornflowerBlue().WithAlpha(0.75),
2037  .blend_mode = BlendMode::kSourceOver});
2038 
2039  std::shared_ptr<ContextSpy> spy = ContextSpy::Make();
2040  Picture picture = canvas.EndRecordingAsPicture();
2041  std::shared_ptr<Context> real_context = GetContext();
2042  std::shared_ptr<ContextMock> mock_context = spy->MakeContext(real_context);
2043  AiksContext renderer(mock_context, nullptr);
2044  std::shared_ptr<Image> image = picture.ToImage(renderer, {300, 300});
2045 
2046  ASSERT_EQ(spy->render_passes_.size(), 1llu);
2047  std::shared_ptr<RenderPass> render_pass = spy->render_passes_[0];
2048  ASSERT_EQ(render_pass->GetCommands().size(), 2llu);
2049 }

References impeller::Color::CornflowerBlue(), impeller::Canvas::DrawRRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::kSource, impeller::kSourceOver, impeller::TRect< Scalar >::MakeXYWH(), impeller::Color::Red(), impeller::Picture::ToImage(), and impeller::Color::WithAlpha().

◆ TEST_P() [133/419]

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

Definition at line 314 of file aiks_path_unittests.cc.

314  {
315  Canvas canvas;
316  Paint paint;
317  paint.color = Color::Red();
318  paint.style = Paint::Style::kStroke;
319  paint.stroke_width = 10;
320 
321  canvas.Translate({100, 100});
322  canvas.DrawPath(
323  PathBuilder{}.AddRect(Rect::MakeSize(Size{100, 100})).TakePath(),
324  {paint});
325 
326  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
327 }

References impeller::PathBuilder::AddRect(), impeller::Paint::color, impeller::Canvas::DrawPath(), impeller::Canvas::EndRecordingAsPicture(), impeller::Paint::kStroke, impeller::TRect< Scalar >::MakeSize(), impeller::Color::Red(), impeller::Paint::stroke_width, impeller::Paint::style, and impeller::Canvas::Translate().

◆ TEST_P() [134/419]

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

Definition at line 329 of file aiks_path_unittests.cc.

329  {
330  Canvas canvas;
331  Paint paint;
332  paint.color = Color::Red();
333  paint.style = Paint::Style::kStroke;
334  paint.stroke_width = 10;
335  paint.stroke_join = Join::kBevel;
336 
337  canvas.Translate({100, 100});
338  canvas.DrawPath(
339  PathBuilder{}.AddRect(Rect::MakeSize(Size{100, 100})).TakePath(),
340  {paint});
341 
342  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
343 }

References impeller::PathBuilder::AddRect(), impeller::Paint::color, impeller::Canvas::DrawPath(), impeller::Canvas::EndRecordingAsPicture(), impeller::kBevel, impeller::Paint::kStroke, impeller::TRect< Scalar >::MakeSize(), impeller::Color::Red(), impeller::Paint::stroke_join, impeller::Paint::stroke_width, impeller::Paint::style, and impeller::Canvas::Translate().

◆ TEST_P() [135/419]

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

Definition at line 2998 of file aiks_unittests.cc.

2998  {
2999  Canvas canvas;
3000  canvas.Transform(Matrix(1.0, 0.0, 0.0, 0.0, //
3001  0.0, 1.0, 0.0, 0.0, //
3002  0.0, 0.0, 1.0, 0.01, //
3003  0.0, 0.0, 0.0, 1.0) * //
3004  Matrix::MakeRotationY({Degrees{10}}));
3005 
3006  ASSERT_TRUE(RenderTextInCanvasSkia(GetContext(), canvas, "Hello world",
3007  "Roboto-Regular.ttf"));
3008 
3009  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3010 }

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

◆ TEST_P() [136/419]

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

Definition at line 3012 of file aiks_unittests.cc.

3012  {
3013  Canvas canvas;
3014  Paint save_paint;
3015  canvas.SaveLayer(save_paint);
3016  canvas.Transform(Matrix(1.0, 0.0, 0.0, 0.0, //
3017  0.0, 1.0, 0.0, 0.0, //
3018  0.0, 0.0, 1.0, 0.01, //
3019  0.0, 0.0, 0.0, 1.0) * //
3020  Matrix::MakeRotationY({Degrees{10}}));
3021 
3022  ASSERT_TRUE(RenderTextInCanvasSkia(GetContext(), canvas, "Hello world",
3023  "Roboto-Regular.ttf"));
3024  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3025 }

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

◆ TEST_P() [137/419]

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

Definition at line 3244 of file aiks_unittests.cc.

3244  {
3245  Canvas canvas;
3246  canvas.Scale(GetContentScale());
3247  canvas.DrawPaint(Paint{.color = Color::Red()});
3248  canvas.ClipRect(Rect::MakeXYWH(100, 100, 200, 200));
3249  canvas.SaveLayer(Paint{.color = Color::Blue()});
3250  canvas.Restore();
3251  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3252 }

References impeller::Color::Blue(), impeller::Canvas::ClipRect(), impeller::Paint::color, impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Color::Red(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Canvas::Scale().

◆ TEST_P() [138/419]

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

Definition at line 3254 of file aiks_unittests.cc.

3254  {
3255  Canvas canvas;
3256  canvas.Scale(GetContentScale());
3257  auto image = std::make_shared<Image>(CreateTextureForFixture("airplane.jpg"));
3258  canvas.DrawImage(image, {10, 10}, {});
3259  canvas.ClipRect(Rect::MakeXYWH(100, 100, 200, 200));
3260  canvas.SaveLayer(Paint{.blend_mode = BlendMode::kClear});
3261  canvas.Restore();
3262  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3263 }

References impeller::Paint::blend_mode, impeller::Canvas::ClipRect(), impeller::Canvas::DrawImage(), impeller::Canvas::EndRecordingAsPicture(), impeller::kClear, impeller::TRect< Scalar >::MakeXYWH(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Canvas::Scale().

◆ TEST_P() [139/419]

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

Definition at line 1280 of file aiks_unittests.cc.

1280  {
1281  Canvas canvas;
1282  canvas.Scale(GetContentScale());
1283  Paint paint;
1284  const int color_count = 3;
1285  Color colors[color_count] = {
1286  Color::Blue(),
1287  Color::Green(),
1288  Color::Crimson(),
1289  };
1290 
1291  paint.color = Color::White();
1292  canvas.DrawPaint(paint);
1293 
1294  int c_index = 0;
1295  int radius = 600;
1296  while (radius > 0) {
1297  paint.color = colors[(c_index++) % color_count];
1298  canvas.DrawCircle({10, 10}, radius, paint);
1299  if (radius > 30) {
1300  radius -= 10;
1301  } else {
1302  radius -= 2;
1303  }
1304  }
1305 
1306  std::vector<Color> gradient_colors = {
1307  Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0},
1308  Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0},
1309  Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0},
1310  Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0},
1311  Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0},
1312  Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0},
1313  Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}};
1314  std::vector<Scalar> stops = {
1315  0.0,
1316  (1.0 / 6.0) * 1,
1317  (1.0 / 6.0) * 2,
1318  (1.0 / 6.0) * 3,
1319  (1.0 / 6.0) * 4,
1320  (1.0 / 6.0) * 5,
1321  1.0,
1322  };
1323  auto texture = CreateTextureForFixture("airplane.jpg",
1324  /*enable_mipmapping=*/true);
1325 
1326  paint.color_source = ColorSource::MakeRadialGradient(
1327  {500, 600}, 75, std::move(gradient_colors), std::move(stops),
1328  Entity::TileMode::kMirror, {});
1329  canvas.DrawCircle({500, 600}, 100, paint);
1330 
1331  paint.color_source = ColorSource::MakeImage(
1332  texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {},
1333  Matrix::MakeTranslation({700, 200}));
1334  canvas.DrawCircle({800, 300}, 100, paint);
1335 
1336  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1337 }

References impeller::Color::Blue(), impeller::Paint::color, impeller::Paint::color_source, impeller::Color::Crimson(), impeller::Canvas::DrawCircle(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::Entity::kMirror, impeller::Entity::kRepeat, impeller::ColorSource::MakeImage(), impeller::ColorSource::MakeRadialGradient(), impeller::Matrix::MakeTranslation(), impeller::Canvas::Scale(), and impeller::Color::White().

◆ TEST_P() [140/419]

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

Definition at line 1403 of file aiks_unittests.cc.

1403  {
1404  Canvas canvas;
1405  canvas.Scale(GetContentScale());
1406  Paint paint;
1407  const int color_count = 3;
1408  Color colors[color_count] = {
1409  Color::Blue(),
1410  Color::Green(),
1411  Color::Crimson(),
1412  };
1413 
1414  paint.color = Color::White();
1415  canvas.DrawPaint(paint);
1416 
1417  int c_index = 0;
1418  int long_radius = 600;
1419  int short_radius = 600;
1420  while (long_radius > 0 && short_radius > 0) {
1421  paint.color = colors[(c_index++) % color_count];
1422  canvas.DrawOval(Rect::MakeXYWH(10 - long_radius, 10 - short_radius,
1423  long_radius * 2, short_radius * 2),
1424  paint);
1425  canvas.DrawOval(Rect::MakeXYWH(1000 - short_radius, 750 - long_radius,
1426  short_radius * 2, long_radius * 2),
1427  paint);
1428  if (short_radius > 30) {
1429  short_radius -= 10;
1430  long_radius -= 5;
1431  } else {
1432  short_radius -= 2;
1433  long_radius -= 1;
1434  }
1435  }
1436 
1437  std::vector<Color> gradient_colors = {
1438  Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0},
1439  Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0},
1440  Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0},
1441  Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0},
1442  Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0},
1443  Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0},
1444  Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}};
1445  std::vector<Scalar> stops = {
1446  0.0,
1447  (1.0 / 6.0) * 1,
1448  (1.0 / 6.0) * 2,
1449  (1.0 / 6.0) * 3,
1450  (1.0 / 6.0) * 4,
1451  (1.0 / 6.0) * 5,
1452  1.0,
1453  };
1454  auto texture = CreateTextureForFixture("airplane.jpg",
1455  /*enable_mipmapping=*/true);
1456 
1457  paint.color = Color::White().WithAlpha(0.5);
1458 
1459  paint.color_source = ColorSource::MakeRadialGradient(
1460  {300, 650}, 75, std::move(gradient_colors), std::move(stops),
1461  Entity::TileMode::kMirror, {});
1462  canvas.DrawOval(Rect::MakeXYWH(200, 625, 200, 50), paint);
1463  canvas.DrawOval(Rect::MakeXYWH(275, 550, 50, 200), paint);
1464 
1465  paint.color_source = ColorSource::MakeImage(
1466  texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {},
1467  Matrix::MakeTranslation({610, 15}));
1468  canvas.DrawOval(Rect::MakeXYWH(610, 90, 200, 50), paint);
1469  canvas.DrawOval(Rect::MakeXYWH(685, 15, 50, 200), paint);
1470 
1471  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1472 }

References impeller::Color::Blue(), impeller::Paint::color, impeller::Paint::color_source, impeller::Color::Crimson(), impeller::Canvas::DrawOval(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::Entity::kMirror, impeller::Entity::kRepeat, impeller::ColorSource::MakeImage(), impeller::ColorSource::MakeRadialGradient(), impeller::Matrix::MakeTranslation(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Canvas::Scale(), impeller::Color::White(), and impeller::Color::WithAlpha().

◆ TEST_P() [141/419]

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

Definition at line 1618 of file aiks_unittests.cc.

1618  {
1619  Canvas canvas;
1620  canvas.Scale(GetContentScale());
1621  Paint paint;
1622  const int color_count = 3;
1623  Color colors[color_count] = {
1624  Color::Blue(),
1625  Color::Green(),
1626  Color::Crimson(),
1627  };
1628 
1629  paint.color = Color::White();
1630  canvas.DrawPaint(paint);
1631 
1632  auto draw_rrect_as_path = [&canvas](const Rect& rect, const Size& radii,
1633  const Paint& paint) {
1634  PathBuilder builder = PathBuilder();
1635  builder.AddRoundedRect(rect, radii);
1636  canvas.DrawPath(builder.TakePath(), paint);
1637  };
1638 
1639  int c_index = 0;
1640  for (int i = 0; i < 4; i++) {
1641  for (int j = 0; j < 4; j++) {
1642  paint.color = colors[(c_index++) % color_count];
1643  draw_rrect_as_path(Rect::MakeXYWH(i * 100 + 10, j * 100 + 20, 80, 80),
1644  Size(i * 5 + 10, j * 5 + 10), paint);
1645  }
1646  }
1647  paint.color = colors[(c_index++) % color_count];
1648  draw_rrect_as_path(Rect::MakeXYWH(10, 420, 380, 80), Size(40, 40), paint);
1649  paint.color = colors[(c_index++) % color_count];
1650  draw_rrect_as_path(Rect::MakeXYWH(410, 20, 80, 380), Size(40, 40), paint);
1651 
1652  std::vector<Color> gradient_colors = {
1653  Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0},
1654  Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0},
1655  Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0},
1656  Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0},
1657  Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0},
1658  Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0},
1659  Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}};
1660  std::vector<Scalar> stops = {
1661  0.0,
1662  (1.0 / 6.0) * 1,
1663  (1.0 / 6.0) * 2,
1664  (1.0 / 6.0) * 3,
1665  (1.0 / 6.0) * 4,
1666  (1.0 / 6.0) * 5,
1667  1.0,
1668  };
1669  auto texture = CreateTextureForFixture("airplane.jpg",
1670  /*enable_mipmapping=*/true);
1671 
1672  paint.color = Color::White().WithAlpha(0.1);
1673  paint.color_source = ColorSource::MakeRadialGradient(
1674  {550, 550}, 75, gradient_colors, stops, Entity::TileMode::kMirror, {});
1675  for (int i = 1; i <= 10; i++) {
1676  int j = 11 - i;
1677  draw_rrect_as_path(Rect::MakeLTRB(550 - i * 20, 550 - j * 20, //
1678  550 + i * 20, 550 + j * 20),
1679  Size(i * 10, j * 10), paint);
1680  }
1681  paint.color = Color::White().WithAlpha(0.5);
1682  paint.color_source = ColorSource::MakeRadialGradient(
1683  {200, 650}, 75, std::move(gradient_colors), std::move(stops),
1684  Entity::TileMode::kMirror, {});
1685  draw_rrect_as_path(Rect::MakeLTRB(100, 610, 300, 690), Size(40, 40), paint);
1686  draw_rrect_as_path(Rect::MakeLTRB(160, 550, 240, 750), Size(40, 40), paint);
1687 
1688  paint.color = Color::White().WithAlpha(0.1);
1689  paint.color_source = ColorSource::MakeImage(
1690  texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {},
1691  Matrix::MakeTranslation({520, 20}));
1692  for (int i = 1; i <= 10; i++) {
1693  int j = 11 - i;
1694  draw_rrect_as_path(Rect::MakeLTRB(720 - i * 20, 220 - j * 20, //
1695  720 + i * 20, 220 + j * 20),
1696  Size(i * 10, j * 10), paint);
1697  }
1698  paint.color = Color::White().WithAlpha(0.5);
1699  paint.color_source = ColorSource::MakeImage(
1700  texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {},
1701  Matrix::MakeTranslation({800, 300}));
1702  draw_rrect_as_path(Rect::MakeLTRB(800, 410, 1000, 490), Size(40, 40), paint);
1703  draw_rrect_as_path(Rect::MakeLTRB(860, 350, 940, 550), Size(40, 40), paint);
1704 
1705  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1706 }

References impeller::PathBuilder::AddRoundedRect(), impeller::Color::Blue(), impeller::Paint::color, impeller::Paint::color_source, impeller::Color::Crimson(), impeller::Canvas::DrawPaint(), impeller::Canvas::DrawPath(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::Entity::kMirror, impeller::Entity::kRepeat, impeller::ColorSource::MakeImage(), impeller::TRect< Scalar >::MakeLTRB(), impeller::ColorSource::MakeRadialGradient(), impeller::Matrix::MakeTranslation(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Canvas::Scale(), impeller::PathBuilder::TakePath(), impeller::Color::White(), and impeller::Color::WithAlpha().

◆ TEST_P() [142/419]

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

Definition at line 1474 of file aiks_unittests.cc.

1474  {
1475  Canvas canvas;
1476  canvas.Scale(GetContentScale());
1477  Paint paint;
1478  const int color_count = 3;
1479  Color colors[color_count] = {
1480  Color::Blue(),
1481  Color::Green(),
1482  Color::Crimson(),
1483  };
1484 
1485  paint.color = Color::White();
1486  canvas.DrawPaint(paint);
1487 
1488  int c_index = 0;
1489  for (int i = 0; i < 4; i++) {
1490  for (int j = 0; j < 4; j++) {
1491  paint.color = colors[(c_index++) % color_count];
1492  canvas.DrawRRect(Rect::MakeXYWH(i * 100 + 10, j * 100 + 20, 80, 80),
1493  Size(i * 5 + 10, j * 5 + 10), paint);
1494  }
1495  }
1496  paint.color = colors[(c_index++) % color_count];
1497  canvas.DrawRRect(Rect::MakeXYWH(10, 420, 380, 80), Size(40, 40), paint);
1498  paint.color = colors[(c_index++) % color_count];
1499  canvas.DrawRRect(Rect::MakeXYWH(410, 20, 80, 380), Size(40, 40), paint);
1500 
1501  std::vector<Color> gradient_colors = {
1502  Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0},
1503  Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0},
1504  Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0},
1505  Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0},
1506  Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0},
1507  Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0},
1508  Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}};
1509  std::vector<Scalar> stops = {
1510  0.0,
1511  (1.0 / 6.0) * 1,
1512  (1.0 / 6.0) * 2,
1513  (1.0 / 6.0) * 3,
1514  (1.0 / 6.0) * 4,
1515  (1.0 / 6.0) * 5,
1516  1.0,
1517  };
1518  auto texture = CreateTextureForFixture("airplane.jpg",
1519  /*enable_mipmapping=*/true);
1520 
1521  paint.color = Color::White().WithAlpha(0.1);
1522  paint.color_source = ColorSource::MakeRadialGradient(
1523  {550, 550}, 75, gradient_colors, stops, Entity::TileMode::kMirror, {});
1524  for (int i = 1; i <= 10; i++) {
1525  int j = 11 - i;
1526  canvas.DrawRRect(Rect::MakeLTRB(550 - i * 20, 550 - j * 20, //
1527  550 + i * 20, 550 + j * 20),
1528  Size(i * 10, j * 10), paint);
1529  }
1530  paint.color = Color::White().WithAlpha(0.5);
1531  paint.color_source = ColorSource::MakeRadialGradient(
1532  {200, 650}, 75, std::move(gradient_colors), std::move(stops),
1533  Entity::TileMode::kMirror, {});
1534  canvas.DrawRRect(Rect::MakeLTRB(100, 610, 300, 690), Size(40, 40), paint);
1535  canvas.DrawRRect(Rect::MakeLTRB(160, 550, 240, 750), Size(40, 40), paint);
1536 
1537  paint.color = Color::White().WithAlpha(0.1);
1538  paint.color_source = ColorSource::MakeImage(
1539  texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {},
1540  Matrix::MakeTranslation({520, 20}));
1541  for (int i = 1; i <= 10; i++) {
1542  int j = 11 - i;
1543  canvas.DrawRRect(Rect::MakeLTRB(720 - i * 20, 220 - j * 20, //
1544  720 + i * 20, 220 + j * 20),
1545  Size(i * 10, j * 10), paint);
1546  }
1547  paint.color = Color::White().WithAlpha(0.5);
1548  paint.color_source = ColorSource::MakeImage(
1549  texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {},
1550  Matrix::MakeTranslation({800, 300}));
1551  canvas.DrawRRect(Rect::MakeLTRB(800, 410, 1000, 490), Size(40, 40), paint);
1552  canvas.DrawRRect(Rect::MakeLTRB(860, 350, 940, 550), Size(40, 40), paint);
1553 
1554  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1555 }

References impeller::Color::Blue(), impeller::Paint::color, impeller::Paint::color_source, impeller::Color::Crimson(), impeller::Canvas::DrawPaint(), impeller::Canvas::DrawRRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::Entity::kMirror, impeller::Entity::kRepeat, impeller::ColorSource::MakeImage(), impeller::TRect< Scalar >::MakeLTRB(), impeller::ColorSource::MakeRadialGradient(), impeller::Matrix::MakeTranslation(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Canvas::Scale(), impeller::Color::White(), and impeller::Color::WithAlpha().

◆ TEST_P() [143/419]

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

Definition at line 2169 of file aiks_unittests.cc.

2169  {
2170  Canvas canvas;
2171 
2172  canvas.SaveLayer({
2173  .color_filter =
2174  ColorFilter::MakeBlend(BlendMode::kColorDodge, Color::Red()),
2175  });
2176 
2177  canvas.Translate({500, 300, 0});
2178  canvas.Rotate(Radians(2 * kPi / 3));
2179  canvas.DrawRect(Rect::MakeXYWH(100, 100, 200, 200), {.color = Color::Blue()});
2180 
2181  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2182 }

References impeller::Color::Blue(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::kColorDodge, impeller::kPi, impeller::ColorFilter::MakeBlend(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Color::Red(), impeller::Canvas::Rotate(), impeller::Canvas::SaveLayer(), and impeller::Canvas::Translate().

◆ TEST_P() [144/419]

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

Definition at line 1008 of file aiks_blur_unittests.cc.

1008  {
1009  size_t blur_required_mip_count =
1010  GetParam() == PlaygroundBackend::kOpenGLES ? 1 : 4;
1011 
1012  Canvas canvas;
1013  canvas.DrawCircle({100, 100}, 50, {.color = Color::CornflowerBlue()});
1014  canvas.SaveLayer({}, std::nullopt,
1015  ImageFilter::MakeBlur(Sigma(3), Sigma(3),
1016  FilterContents::BlurStyle::kNormal,
1017  Entity::TileMode::kClamp));
1018  canvas.Restore();
1019 
1020  Picture picture = canvas.EndRecordingAsPicture();
1021  std::shared_ptr<RenderTargetCache> cache =
1022  std::make_shared<RenderTargetCache>(GetContext()->GetResourceAllocator());
1023  AiksContext aiks_context(GetContext(), nullptr, cache);
1024  picture.ToImage(aiks_context, {100, 100});
1025 
1026  size_t max_mip_count = 0;
1027  for (auto it = cache->GetRenderTargetDataBegin();
1028  it != cache->GetRenderTargetDataEnd(); ++it) {
1029  max_mip_count = std::max(it->config.mip_count, max_mip_count);
1030  }
1031  EXPECT_EQ(max_mip_count, blur_required_mip_count);
1032 }

References impeller::Color::CornflowerBlue(), impeller::Canvas::DrawCircle(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kClamp, impeller::FilterContents::kNormal, impeller::kOpenGLES, impeller::ImageFilter::MakeBlur(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Picture::ToImage().

◆ TEST_P() [145/419]

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

Definition at line 714 of file aiks_blur_unittests.cc.

714  {
715  // This test is for checking out how stable rendering is when content is
716  // translated underneath a blur. Animating under a blur can cause
717  // *shimmering* to happen as a result of pixel alignment.
718  // See also: https://github.com/flutter/flutter/issues/140193
719  auto boston = std::make_shared<Image>(
720  CreateTextureForFixture("boston.jpg", /*enable_mipmapping=*/true));
721  ASSERT_TRUE(boston);
722  int64_t count = 0;
723  Scalar sigma = 20.0;
724  Scalar freq = 0.1;
725  Scalar amp = 50.0;
726  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
727  if (AiksTest::ImGuiBegin("Controls", nullptr,
728  ImGuiWindowFlags_AlwaysAutoResize)) {
729  ImGui::SliderFloat("Sigma", &sigma, 0, 200);
730  ImGui::SliderFloat("Frequency", &freq, 0.01, 2.0);
731  ImGui::SliderFloat("Amplitude", &amp, 1, 100);
732  ImGui::End();
733  }
734 
735  Canvas canvas;
736  canvas.Scale(GetContentScale());
737  Scalar y = amp * sin(freq * 2.0 * M_PI * count / 60);
738  canvas.DrawImage(boston,
739  Point(1024 / 2 - boston->GetSize().width / 2,
740  (768 / 2 - boston->GetSize().height / 2) + y),
741  {});
742  static PlaygroundPoint point_a(Point(100, 100), 20, Color::Red());
743  static PlaygroundPoint point_b(Point(900, 700), 20, Color::Red());
744  auto [handle_a, handle_b] = DrawPlaygroundLine(point_a, point_b);
745  canvas.ClipRect(
746  Rect::MakeLTRB(handle_a.x, handle_a.y, handle_b.x, handle_b.y));
747  canvas.ClipRect(Rect::MakeLTRB(100, 100, 900, 700));
748  canvas.SaveLayer({.blend_mode = BlendMode::kSource}, std::nullopt,
749  ImageFilter::MakeBlur(Sigma(sigma), Sigma(sigma),
750  FilterContents::BlurStyle::kNormal,
751  Entity::TileMode::kClamp));
752  count += 1;
753  return canvas.EndRecordingAsPicture();
754  };
755  ASSERT_TRUE(OpenPlaygroundHere(callback));
756 }

References impeller::Canvas::ClipRect(), impeller::Canvas::DrawImage(), impeller::DrawPlaygroundLine(), impeller::Canvas::EndRecordingAsPicture(), impeller::AiksPlayground::ImGuiBegin(), impeller::Entity::kClamp, impeller::FilterContents::kNormal, impeller::kSource, impeller::ImageFilter::MakeBlur(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Color::Red(), impeller::Canvas::SaveLayer(), and impeller::Canvas::Scale().

◆ TEST_P() [146/419]

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

Definition at line 469 of file aiks_blur_unittests.cc.

469  {
470  Canvas canvas;
471 
472  canvas.Scale(GetContentScale());
473  std::shared_ptr<Texture> boston = CreateTextureForFixture("boston.jpg");
474  canvas.DrawImageRect(
475  std::make_shared<Image>(boston),
476  Rect::MakeXYWH(0, 0, boston->GetSize().width, boston->GetSize().height),
477  Rect::MakeLTRB(0, 0, GetWindowSize().width, 100), Paint{});
478  canvas.DrawRRect(Rect::MakeLTRB(0, 110, GetWindowSize().width, 210),
479  Size(10, 10), Paint{.color = Color::Magenta()});
480  canvas.ClipRect(Rect::MakeLTRB(0, 50, GetWindowSize().width, 150));
481  canvas.SaveLayer({.blend_mode = BlendMode::kSource}, std::nullopt,
482  ImageFilter::MakeBlur(Sigma(20.0), Sigma(20.0),
483  FilterContents::BlurStyle::kNormal,
484  Entity::TileMode::kClamp));
485  canvas.Restore();
486  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
487 }

References impeller::Canvas::ClipRect(), impeller::Paint::color, impeller::Canvas::DrawImageRect(), impeller::Canvas::DrawRRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kClamp, impeller::FilterContents::kNormal, impeller::kSource, impeller::Color::Magenta(), impeller::ImageFilter::MakeBlur(), impeller::TRect< Scalar >::MakeLTRB(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Canvas::Scale().

◆ TEST_P() [147/419]

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

Definition at line 451 of file aiks_blur_unittests.cc.

451  {
452  Canvas canvas;
453 
454  canvas.Scale(GetContentScale());
455  canvas.DrawRRect(Rect::MakeLTRB(0, 0, GetWindowSize().width, 100),
456  Size(10, 10), Paint{.color = Color::LimeGreen()});
457  canvas.DrawRRect(Rect::MakeLTRB(0, 110, GetWindowSize().width, 210),
458  Size(10, 10), Paint{.color = Color::Magenta()});
459  canvas.ClipRect(Rect::MakeLTRB(100, 0, 200, GetWindowSize().height));
460  canvas.SaveLayer({.blend_mode = BlendMode::kSource}, std::nullopt,
461  ImageFilter::MakeBlur(Sigma(20.0), Sigma(20.0),
462  FilterContents::BlurStyle::kNormal,
463  Entity::TileMode::kClamp));
464  canvas.Restore();
465 
466  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
467 }

References impeller::Canvas::ClipRect(), impeller::Paint::color, impeller::Canvas::DrawRRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kClamp, impeller::FilterContents::kNormal, impeller::kSource, impeller::Color::LimeGreen(), impeller::Color::Magenta(), impeller::ImageFilter::MakeBlur(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Canvas::Scale().

◆ TEST_P() [148/419]

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

Definition at line 688 of file aiks_blur_unittests.cc.

688  {
689  for (int32_t i = 0; i < 5; ++i) {
690  Canvas canvas;
691  ISize clip_size = ISize(i, i);
692  canvas.ClipRect(
693  Rect::MakeXYWH(400, 400, clip_size.width, clip_size.height));
694  canvas.DrawCircle(
695  {400, 400}, 200,
696  {
697  .color = Color::Green(),
698  .image_filter = ImageFilter::MakeBlur(
699  Sigma(0.1), Sigma(0.1), FilterContents::BlurStyle::kNormal,
700  Entity::TileMode::kDecal),
701  });
702  canvas.Restore();
703 
704  Picture picture = canvas.EndRecordingAsPicture();
705  std::shared_ptr<RenderTargetCache> cache =
706  std::make_shared<RenderTargetCache>(
707  GetContext()->GetResourceAllocator());
708  AiksContext aiks_context(GetContext(), nullptr, cache);
709  std::shared_ptr<Image> image = picture.ToImage(aiks_context, {1024, 768});
710  EXPECT_TRUE(image) << " clip rect " << i;
711  }
712 }

References impeller::Canvas::ClipRect(), impeller::Canvas::DrawCircle(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::TSize< T >::height, impeller::Entity::kDecal, impeller::FilterContents::kNormal, impeller::ImageFilter::MakeBlur(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Canvas::Restore(), impeller::Picture::ToImage(), and impeller::TSize< T >::width.

◆ TEST_P() [149/419]

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

Definition at line 1073 of file aiks_blur_unittests.cc.

1073  {
1074  size_t blur_required_mip_count =
1075  GetParam() == PlaygroundBackend::kOpenGLES ? 1 : 4;
1076  fml::testing::LogCapture log_capture;
1077  Canvas canvas;
1078  canvas.SaveLayer(
1079  {.image_filter = ImageFilter::MakeBlur(Sigma(30), Sigma(30),
1080  FilterContents::BlurStyle::kNormal,
1081  Entity::TileMode::kClamp)});
1082  canvas.DrawCircle({200, 200}, 50, {.color = Color::Chartreuse()});
1083 
1084  Picture picture = canvas.EndRecordingAsPicture();
1085  std::shared_ptr<RenderTargetCache> cache =
1086  std::make_shared<RenderTargetCache>(GetContext()->GetResourceAllocator());
1087  AiksContext aiks_context(GetContext(), nullptr, cache);
1088  picture.ToImage(aiks_context, {1024, 768});
1089 
1090  size_t max_mip_count = 0;
1091  for (auto it = cache->GetRenderTargetDataBegin();
1092  it != cache->GetRenderTargetDataEnd(); ++it) {
1093  max_mip_count = std::max(it->config.mip_count, max_mip_count);
1094  }
1095  EXPECT_EQ(max_mip_count, blur_required_mip_count);
1096  // The log is FML_DLOG, so only check in debug builds.
1097 #ifndef NDEBUG
1098  if (GetParam() != PlaygroundBackend::kOpenGLES) {
1099  EXPECT_EQ(log_capture.str().find(GaussianBlurFilterContents::kNoMipsError),
1100  std::string::npos);
1101  } else {
1102  EXPECT_NE(log_capture.str().find(GaussianBlurFilterContents::kNoMipsError),
1103  std::string::npos);
1104  }
1105 #endif
1106 }

References impeller::Color::Chartreuse(), impeller::Canvas::DrawCircle(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kClamp, impeller::GaussianBlurFilterContents::kNoMipsError, impeller::FilterContents::kNormal, impeller::kOpenGLES, impeller::ImageFilter::MakeBlur(), impeller::Canvas::SaveLayer(), and impeller::Picture::ToImage().

◆ TEST_P() [150/419]

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

Definition at line 1034 of file aiks_blur_unittests.cc.

1034  {
1035  fml::testing::LogCapture log_capture;
1036  size_t blur_required_mip_count =
1037  GetParam() == PlaygroundBackend::kOpenGLES ? 1 : 4;
1038 
1039  Canvas canvas;
1040  canvas.DrawPaint({.color = Color::Wheat()});
1041  canvas.SaveLayer({.blend_mode = BlendMode::kMultiply});
1042  canvas.DrawCircle({100, 100}, 50, {.color = Color::CornflowerBlue()});
1043  canvas.SaveLayer({}, std::nullopt,
1044  ImageFilter::MakeBlur(Sigma(30), Sigma(30),
1045  FilterContents::BlurStyle::kNormal,
1046  Entity::TileMode::kClamp));
1047  canvas.DrawCircle({200, 200}, 50, {.color = Color::Chartreuse()});
1048 
1049  Picture picture = canvas.EndRecordingAsPicture();
1050  std::shared_ptr<RenderTargetCache> cache =
1051  std::make_shared<RenderTargetCache>(GetContext()->GetResourceAllocator());
1052  AiksContext aiks_context(GetContext(), nullptr, cache);
1053  picture.ToImage(aiks_context, {100, 100});
1054 
1055  size_t max_mip_count = 0;
1056  for (auto it = cache->GetRenderTargetDataBegin();
1057  it != cache->GetRenderTargetDataEnd(); ++it) {
1058  max_mip_count = std::max(it->config.mip_count, max_mip_count);
1059  }
1060  EXPECT_EQ(max_mip_count, blur_required_mip_count);
1061  // The log is FML_DLOG, so only check in debug builds.
1062 #ifndef NDEBUG
1063  if (GetParam() != PlaygroundBackend::kOpenGLES) {
1064  EXPECT_EQ(log_capture.str().find(GaussianBlurFilterContents::kNoMipsError),
1065  std::string::npos);
1066  } else {
1067  EXPECT_NE(log_capture.str().find(GaussianBlurFilterContents::kNoMipsError),
1068  std::string::npos);
1069  }
1070 #endif
1071 }

References impeller::Color::Chartreuse(), impeller::Color::CornflowerBlue(), impeller::Canvas::DrawCircle(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kClamp, impeller::kMultiply, impeller::GaussianBlurFilterContents::kNoMipsError, impeller::FilterContents::kNormal, impeller::kOpenGLES, impeller::ImageFilter::MakeBlur(), impeller::Canvas::SaveLayer(), impeller::Picture::ToImage(), and impeller::Color::Wheat().

◆ TEST_P() [151/419]

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

Definition at line 1108 of file aiks_blur_unittests.cc.

1108  {
1109  size_t blur_required_mip_count =
1110  GetParam() == PlaygroundBackend::kOpenGLES ? 1 : 4;
1111  fml::testing::LogCapture log_capture;
1112  Canvas canvas;
1113  canvas.DrawPath(PathBuilder{}
1114  .MoveTo({100, 100})
1115  .LineTo({200, 100})
1116  .LineTo({150, 200})
1117  .LineTo({50, 200})
1118  .Close()
1119  .TakePath(),
1120  {.color = Color::Chartreuse(),
1121  .image_filter = ImageFilter::MakeBlur(
1122  Sigma(30), Sigma(30), FilterContents::BlurStyle::kNormal,
1123  Entity::TileMode::kClamp)});
1124 
1125  Picture picture = canvas.EndRecordingAsPicture();
1126  std::shared_ptr<RenderTargetCache> cache =
1127  std::make_shared<RenderTargetCache>(GetContext()->GetResourceAllocator());
1128  AiksContext aiks_context(GetContext(), nullptr, cache);
1129  picture.ToImage(aiks_context, {1024, 768});
1130 
1131  size_t max_mip_count = 0;
1132  for (auto it = cache->GetRenderTargetDataBegin();
1133  it != cache->GetRenderTargetDataEnd(); ++it) {
1134  max_mip_count = std::max(it->config.mip_count, max_mip_count);
1135  }
1136  EXPECT_EQ(max_mip_count, blur_required_mip_count);
1137  // The log is FML_DLOG, so only check in debug builds.
1138 #ifndef NDEBUG
1139  if (GetParam() != PlaygroundBackend::kOpenGLES) {
1140  EXPECT_EQ(log_capture.str().find(GaussianBlurFilterContents::kNoMipsError),
1141  std::string::npos);
1142  } else {
1143  EXPECT_NE(log_capture.str().find(GaussianBlurFilterContents::kNoMipsError),
1144  std::string::npos);
1145  }
1146 #endif
1147 }

References impeller::Color::Chartreuse(), impeller::Close(), impeller::Canvas::DrawPath(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kClamp, impeller::GaussianBlurFilterContents::kNoMipsError, impeller::FilterContents::kNormal, impeller::kOpenGLES, impeller::LineTo(), impeller::ImageFilter::MakeBlur(), impeller::PathBuilder::MoveTo(), and impeller::Picture::ToImage().

◆ TEST_P() [152/419]

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

Definition at line 541 of file aiks_blur_unittests.cc.

541  {
542  Canvas canvas;
543 
544  canvas.Scale(GetContentScale());
545  canvas.Scale({0.5, 0.5, 1.0});
546  std::shared_ptr<Texture> boston = CreateTextureForFixture("boston.jpg");
547  canvas.DrawImage(std::make_shared<Image>(boston), Point(100, 100), Paint{});
548  canvas.SaveLayer({.blend_mode = BlendMode::kSource}, std::nullopt,
549  ImageFilter::MakeBlur(Sigma(50.0), Sigma(0.0),
550  FilterContents::BlurStyle::kNormal,
551  Entity::TileMode::kClamp));
552  canvas.Restore();
553  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
554 }

References impeller::Canvas::DrawImage(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kClamp, impeller::FilterContents::kNormal, impeller::kSource, impeller::ImageFilter::MakeBlur(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Canvas::Scale().

◆ TEST_P() [153/419]

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

Definition at line 560 of file aiks_blur_unittests.cc.

560  {
561  Canvas canvas;
562  std::shared_ptr<Texture> boston = CreateTextureForFixture("boston.jpg");
563  Rect bounds =
564  Rect::MakeXYWH(0, 0, boston->GetSize().width, boston->GetSize().height);
565  Vector2 image_center = Vector2(bounds.GetSize() / 2);
566  Paint paint = {.image_filter =
567  ImageFilter::MakeBlur(Sigma(20.0), Sigma(20.0),
568  FilterContents::BlurStyle::kNormal,
569  Entity::TileMode::kDecal)};
570  Vector2 clip_size = {150, 75};
571  Vector2 center = Vector2(1024, 768) / 2;
572  canvas.Scale(GetContentScale());
573  canvas.ClipRect(
574  Rect::MakeLTRB(center.x, center.y, center.x, center.y).Expand(clip_size));
575  canvas.Translate({center.x, center.y, 0});
576  canvas.Scale({0.6, 0.6, 1});
577  canvas.Rotate(Degrees(25));
578 
579  canvas.DrawImageRect(std::make_shared<Image>(boston), /*source=*/bounds,
580  /*dest=*/bounds.Shift(-image_center), paint);
581 
582  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
583 }

References impeller::Canvas::ClipRect(), impeller::Canvas::DrawImageRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::TRect< T >::Expand(), impeller::TRect< T >::GetSize(), impeller::Paint::image_filter, impeller::Entity::kDecal, impeller::FilterContents::kNormal, impeller::ImageFilter::MakeBlur(), impeller::TRect< Scalar >::MakeLTRB(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Canvas::Rotate(), impeller::Canvas::Scale(), impeller::TRect< T >::Shift(), impeller::Canvas::Translate(), impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ TEST_P() [154/419]

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

Definition at line 609 of file aiks_blur_unittests.cc.

609  {
610  std::shared_ptr<Texture> boston = CreateTextureForFixture("boston.jpg");
611 
612  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
613  const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
614  const Entity::TileMode tile_modes[] = {
615  Entity::TileMode::kClamp, Entity::TileMode::kRepeat,
616  Entity::TileMode::kMirror, Entity::TileMode::kDecal};
617 
618  static float rotation = 0;
619  static float scale = 0.6;
620  static int selected_tile_mode = 3;
621 
622  if (AiksTest::ImGuiBegin("Controls", nullptr,
623  ImGuiWindowFlags_AlwaysAutoResize)) {
624  ImGui::SliderFloat("Rotation (degrees)", &rotation, -180, 180);
625  ImGui::SliderFloat("Scale", &scale, 0, 2.0);
626  ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
627  sizeof(tile_mode_names) / sizeof(char*));
628  ImGui::End();
629  }
630 
631  Canvas canvas;
632  Rect bounds =
633  Rect::MakeXYWH(0, 0, boston->GetSize().width, boston->GetSize().height);
634  Vector2 image_center = Vector2(bounds.GetSize() / 2);
635  Paint paint = {.image_filter =
636  ImageFilter::MakeBlur(Sigma(20.0), Sigma(20.0),
637  FilterContents::BlurStyle::kNormal,
638  tile_modes[selected_tile_mode])};
639  static PlaygroundPoint point_a(Point(362, 309), 20, Color::Red());
640  static PlaygroundPoint point_b(Point(662, 459), 20, Color::Red());
641  auto [handle_a, handle_b] = DrawPlaygroundLine(point_a, point_b);
642  Vector2 center = Vector2(1024, 768) / 2;
643  canvas.Scale(GetContentScale());
644  canvas.ClipRect(
645  Rect::MakeLTRB(handle_a.x, handle_a.y, handle_b.x, handle_b.y));
646  canvas.Translate({center.x, center.y, 0});
647  canvas.Scale({scale, scale, 1});
648  canvas.Rotate(Degrees(rotation));
649 
650  canvas.DrawImageRect(std::make_shared<Image>(boston), /*source=*/bounds,
651  /*dest=*/bounds.Shift(-image_center), paint);
652  return canvas.EndRecordingAsPicture();
653  };
654 
655  ASSERT_TRUE(OpenPlaygroundHere(callback));
656 }

References impeller::Canvas::ClipRect(), impeller::Canvas::DrawImageRect(), impeller::DrawPlaygroundLine(), impeller::Canvas::EndRecordingAsPicture(), impeller::TRect< T >::GetSize(), impeller::Paint::image_filter, impeller::AiksPlayground::ImGuiBegin(), impeller::Entity::kClamp, impeller::Entity::kDecal, impeller::Entity::kMirror, impeller::FilterContents::kNormal, impeller::Entity::kRepeat, impeller::ImageFilter::MakeBlur(), impeller::TRect< Scalar >::MakeLTRB(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Color::Red(), impeller::Canvas::Rotate(), impeller::Canvas::Scale(), scale, impeller::TRect< T >::Shift(), impeller::Canvas::Translate(), impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ TEST_P() [155/419]

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

Definition at line 585 of file aiks_blur_unittests.cc.

585  {
586  Canvas canvas;
587  std::shared_ptr<Texture> boston = CreateTextureForFixture("boston.jpg");
588  Rect bounds =
589  Rect::MakeXYWH(0, 0, boston->GetSize().width, boston->GetSize().height);
590  Vector2 image_center = Vector2(bounds.GetSize() / 2);
591  Paint paint = {.image_filter =
592  ImageFilter::MakeBlur(Sigma(20.0), Sigma(20.0),
593  FilterContents::BlurStyle::kNormal,
594  Entity::TileMode::kDecal)};
595  Vector2 clip_size = {150, 75};
596  Vector2 center = Vector2(1024, 768) / 2;
597  canvas.Scale(GetContentScale());
598  canvas.ClipRect(
599  Rect::MakeLTRB(center.x, center.y, center.x, center.y).Expand(clip_size));
600  canvas.Translate({center.x, center.y, 0});
601  canvas.Scale({0.6, 0.6, 1});
602 
603  canvas.DrawImageRect(std::make_shared<Image>(boston), /*source=*/bounds,
604  /*dest=*/bounds.Shift(-image_center), paint);
605 
606  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
607 }

References impeller::Canvas::ClipRect(), impeller::Canvas::DrawImageRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::TRect< T >::Expand(), impeller::TRect< T >::GetSize(), impeller::Paint::image_filter, impeller::Entity::kDecal, impeller::FilterContents::kNormal, impeller::ImageFilter::MakeBlur(), impeller::TRect< Scalar >::MakeLTRB(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Canvas::Scale(), impeller::TRect< T >::Shift(), impeller::Canvas::Translate(), impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ TEST_P() [156/419]

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

Definition at line 995 of file aiks_blur_unittests.cc.

995  {
996  Canvas canvas;
997  canvas.DrawCircle({100, 100}, 50, {.color = Color::CornflowerBlue()});
998  canvas.SaveLayer({}, std::nullopt,
999  ImageFilter::MakeBlur(Sigma(3), Sigma(3),
1000  FilterContents::BlurStyle::kNormal,
1001  Entity::TileMode::kClamp));
1002  canvas.Restore();
1003 
1004  Picture picture = canvas.EndRecordingAsPicture();
1005  EXPECT_EQ(4, picture.pass->GetRequiredMipCount());
1006 }

References impeller::Color::CornflowerBlue(), impeller::Canvas::DrawCircle(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kClamp, impeller::FilterContents::kNormal, impeller::ImageFilter::MakeBlur(), impeller::Picture::pass, impeller::Canvas::Restore(), and impeller::Canvas::SaveLayer().

◆ TEST_P() [157/419]

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

Definition at line 661 of file aiks_blur_unittests.cc.

661  {
662  for (int32_t i = 1; i < 5; ++i) {
663  Canvas canvas;
664  Scalar fi = i;
665  canvas.DrawPath(
666  PathBuilder{}
667  .MoveTo({100, 100})
668  .LineTo({100.f + fi, 100.f + fi})
669  .TakePath(),
670  {.color = Color::Chartreuse(),
671  .image_filter = ImageFilter::MakeBlur(
672  Sigma(0.1), Sigma(0.1), FilterContents::BlurStyle::kNormal,
673  Entity::TileMode::kClamp)});
674 
675  Picture picture = canvas.EndRecordingAsPicture();
676  std::shared_ptr<RenderTargetCache> cache =
677  std::make_shared<RenderTargetCache>(
678  GetContext()->GetResourceAllocator());
679  AiksContext aiks_context(GetContext(), nullptr, cache);
680  std::shared_ptr<Image> image = picture.ToImage(aiks_context, {1024, 768});
681  EXPECT_TRUE(image) << " length " << i;
682  }
683 }

References impeller::Color::Chartreuse(), impeller::Canvas::DrawPath(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kClamp, impeller::FilterContents::kNormal, impeller::LineTo(), impeller::ImageFilter::MakeBlur(), impeller::PathBuilder::MoveTo(), and impeller::Picture::ToImage().

◆ TEST_P() [158/419]

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

Definition at line 857 of file aiks_blur_unittests.cc.

857  {
858  Canvas canvas;
859  canvas.Scale(GetContentScale());
860 
861  canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
862 
863  Paint paint;
864  paint.color = Color::Green();
865  paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
866  .style = FilterContents::BlurStyle::kInner,
867  .sigma = Sigma(30),
868  };
869  canvas.DrawPath(PathBuilder()
870  .MoveTo({200, 200})
871  .LineTo({300, 400})
872  .LineTo({100, 400})
873  .Close()
874  .TakePath(),
875  paint);
876 
877  // Draw another thing to make sure the clip area is reset.
878  Paint red;
879  red.color = Color::Red();
880  canvas.DrawRect(Rect::MakeXYWH(0, 0, 200, 200), red);
881 
882  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
883 }

References impeller::Close(), impeller::Paint::color, impeller::Canvas::DrawPaint(), impeller::Canvas::DrawPath(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::FilterContents::kInner, impeller::LineTo(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Paint::mask_blur_descriptor, impeller::MoveTo(), impeller::Color::Red(), impeller::Canvas::Scale(), and impeller::Paint::MaskBlurDescriptor::style.

◆ TEST_P() [159/419]

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

Definition at line 758 of file aiks_blur_unittests.cc.

758  {
759  Canvas canvas;
760  canvas.Scale(GetContentScale());
761 
762  canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
763 
764  std::vector<Color> colors = {Color{0.9568, 0.2627, 0.2118, 1.0},
765  Color{0.7568, 0.2627, 0.2118, 1.0}};
766  std::vector<Scalar> stops = {0.0, 1.0};
767 
768  Paint paint;
769  paint.color_source = ColorSource::MakeLinearGradient(
770  {0, 0}, {200, 200}, std::move(colors), std::move(stops),
771  Entity::TileMode::kMirror, {});
772  paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
773  .style = FilterContents::BlurStyle::kInner,
774  .sigma = Sigma(30),
775  };
776  canvas.DrawPath(PathBuilder()
777  .MoveTo({200, 200})
778  .LineTo({300, 400})
779  .LineTo({100, 400})
780  .Close()
781  .TakePath(),
782  paint);
783 
784  // Draw another thing to make sure the clip area is reset.
785  Paint red;
786  red.color = Color::Red();
787  canvas.DrawRect(Rect::MakeXYWH(0, 0, 200, 200), red);
788  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
789 }

References impeller::Close(), impeller::Paint::color, impeller::Paint::color_source, impeller::Canvas::DrawPaint(), impeller::Canvas::DrawPath(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::FilterContents::kInner, impeller::Entity::kMirror, impeller::LineTo(), impeller::ColorSource::MakeLinearGradient(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Paint::mask_blur_descriptor, impeller::MoveTo(), impeller::Color::Red(), impeller::Canvas::Scale(), and impeller::Paint::MaskBlurDescriptor::style.

◆ TEST_P() [160/419]

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

Definition at line 885 of file aiks_blur_unittests.cc.

885  {
886  Canvas canvas;
887  canvas.Scale(GetContentScale());
888 
889  canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
890 
891  Paint paint;
892  paint.color = Color::Green();
893  paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
894  .style = FilterContents::BlurStyle::kOuter,
895  .sigma = Sigma(30),
896  };
897  canvas.DrawPath(PathBuilder()
898  .MoveTo({200, 200})
899  .LineTo({300, 400})
900  .LineTo({100, 400})
901  .Close()
902  .TakePath(),
903  paint);
904 
905  // Draw another thing to make sure the clip area is reset.
906  Paint red;
907  red.color = Color::Red();
908  canvas.DrawRect(Rect::MakeXYWH(0, 0, 200, 200), red);
909 
910  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
911 }

References impeller::Close(), impeller::Paint::color, impeller::Canvas::DrawPaint(), impeller::Canvas::DrawPath(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::FilterContents::kOuter, impeller::LineTo(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Paint::mask_blur_descriptor, impeller::MoveTo(), impeller::Color::Red(), impeller::Canvas::Scale(), and impeller::Paint::MaskBlurDescriptor::style.

◆ TEST_P() [161/419]

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

Definition at line 824 of file aiks_blur_unittests.cc.

824  {
825  Canvas canvas;
826  canvas.Scale(GetContentScale());
827 
828  canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
829 
830  std::vector<Color> colors = {Color{0.9568, 0.2627, 0.2118, 1.0},
831  Color{0.7568, 0.2627, 0.2118, 1.0}};
832  std::vector<Scalar> stops = {0.0, 1.0};
833 
834  Paint paint;
835  paint.color_source = ColorSource::MakeLinearGradient(
836  {0, 0}, {200, 200}, std::move(colors), std::move(stops),
837  Entity::TileMode::kMirror, {});
838  paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
839  .style = FilterContents::BlurStyle::kOuter,
840  .sigma = Sigma(30),
841  };
842  canvas.DrawPath(PathBuilder()
843  .MoveTo({200, 200})
844  .LineTo({300, 400})
845  .LineTo({100, 400})
846  .Close()
847  .TakePath(),
848  paint);
849 
850  // Draw another thing to make sure the clip area is reset.
851  Paint red;
852  red.color = Color::Red();
853  canvas.DrawRect(Rect::MakeXYWH(0, 0, 200, 200), red);
854  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
855 }

References impeller::Close(), impeller::Paint::color, impeller::Paint::color_source, impeller::Canvas::DrawPaint(), impeller::Canvas::DrawPath(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kMirror, impeller::FilterContents::kOuter, impeller::LineTo(), impeller::ColorSource::MakeLinearGradient(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Paint::mask_blur_descriptor, impeller::MoveTo(), impeller::Color::Red(), impeller::Canvas::Scale(), and impeller::Paint::MaskBlurDescriptor::style.

◆ TEST_P() [162/419]

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

Definition at line 913 of file aiks_blur_unittests.cc.

913  {
914  Canvas canvas;
915  canvas.Scale(GetContentScale());
916 
917  canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
918 
919  Paint paint;
920  paint.color = Color::Green();
921  paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
922  .style = FilterContents::BlurStyle::kSolid,
923  .sigma = Sigma(30),
924  };
925  canvas.DrawPath(PathBuilder()
926  .MoveTo({200, 200})
927  .LineTo({300, 400})
928  .LineTo({100, 400})
929  .Close()
930  .TakePath(),
931  paint);
932 
933  // Draw another thing to make sure the clip area is reset.
934  Paint red;
935  red.color = Color::Red();
936  canvas.DrawRect(Rect::MakeXYWH(0, 0, 200, 200), red);
937 
938  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
939 }

References impeller::Close(), impeller::Paint::color, impeller::Canvas::DrawPaint(), impeller::Canvas::DrawPath(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::FilterContents::kSolid, impeller::LineTo(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Paint::mask_blur_descriptor, impeller::MoveTo(), impeller::Color::Red(), impeller::Canvas::Scale(), and impeller::Paint::MaskBlurDescriptor::style.

◆ TEST_P() [163/419]

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

Definition at line 791 of file aiks_blur_unittests.cc.

791  {
792  Canvas canvas;
793  canvas.Scale(GetContentScale());
794 
795  canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
796 
797  std::vector<Color> colors = {Color{0.9568, 0.2627, 0.2118, 1.0},
798  Color{0.7568, 0.2627, 0.2118, 1.0}};
799  std::vector<Scalar> stops = {0.0, 1.0};
800 
801  Paint paint;
802  paint.color_source = ColorSource::MakeLinearGradient(
803  {0, 0}, {200, 200}, std::move(colors), std::move(stops),
804  Entity::TileMode::kMirror, {});
805  paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
806  .style = FilterContents::BlurStyle::kSolid,
807  .sigma = Sigma(30),
808  };
809  canvas.DrawPath(PathBuilder()
810  .MoveTo({200, 200})
811  .LineTo({300, 400})
812  .LineTo({100, 400})
813  .Close()
814  .TakePath(),
815  paint);
816 
817  // Draw another thing to make sure the clip area is reset.
818  Paint red;
819  red.color = Color::Red();
820  canvas.DrawRect(Rect::MakeXYWH(0, 0, 200, 200), red);
821  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
822 }

References impeller::Close(), impeller::Paint::color, impeller::Paint::color_source, impeller::Canvas::DrawPaint(), impeller::Canvas::DrawPath(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kMirror, impeller::FilterContents::kSolid, impeller::LineTo(), impeller::ColorSource::MakeLinearGradient(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Paint::mask_blur_descriptor, impeller::MoveTo(), impeller::Color::Red(), impeller::Canvas::Scale(), and impeller::Paint::MaskBlurDescriptor::style.

◆ TEST_P() [164/419]

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

Definition at line 493 of file aiks_blur_unittests.cc.

493  {
494  if (GetParam() != PlaygroundBackend::kMetal) {
495  GTEST_SKIP_(
496  "This backend doesn't yet support setting device capabilities.");
497  }
498  if (!WillRenderSomething()) {
499  // Sometimes these tests are run without playgrounds enabled which is
500  // pointless for this test since we are asserting that
501  // `SupportsDecalSamplerAddressMode` is called.
502  GTEST_SKIP_("This test requires playgrounds.");
503  }
504 
505  std::shared_ptr<const Capabilities> old_capabilities =
506  GetContext()->GetCapabilities();
507  auto mock_capabilities = std::make_shared<MockCapabilities>();
508  EXPECT_CALL(*mock_capabilities, SupportsDecalSamplerAddressMode())
509  .Times(::testing::AtLeast(1))
510  .WillRepeatedly(::testing::Return(false));
511  FLT_FORWARD(mock_capabilities, old_capabilities, GetDefaultColorFormat);
512  FLT_FORWARD(mock_capabilities, old_capabilities, GetDefaultStencilFormat);
513  FLT_FORWARD(mock_capabilities, old_capabilities,
514  GetDefaultDepthStencilFormat);
515  FLT_FORWARD(mock_capabilities, old_capabilities, SupportsOffscreenMSAA);
516  FLT_FORWARD(mock_capabilities, old_capabilities,
517  SupportsImplicitResolvingMSAA);
518  FLT_FORWARD(mock_capabilities, old_capabilities, SupportsReadFromResolve);
519  FLT_FORWARD(mock_capabilities, old_capabilities, SupportsFramebufferFetch);
520  FLT_FORWARD(mock_capabilities, old_capabilities, SupportsSSBO);
521  FLT_FORWARD(mock_capabilities, old_capabilities, SupportsCompute);
522  FLT_FORWARD(mock_capabilities, old_capabilities,
523  SupportsTextureToTextureBlits);
524  FLT_FORWARD(mock_capabilities, old_capabilities, GetDefaultGlyphAtlasFormat);
525  ASSERT_TRUE(SetCapabilities(mock_capabilities).ok());
526 
527  auto texture = std::make_shared<Image>(CreateTextureForFixture("boston.jpg"));
528  Canvas canvas;
529  canvas.Scale(GetContentScale() * 0.5);
530  canvas.DrawPaint({.color = Color::Black()});
531  canvas.DrawImage(
532  texture, Point(200, 200),
533  {
534  .image_filter = ImageFilter::MakeBlur(
535  Sigma(20.0), Sigma(20.0), FilterContents::BlurStyle::kNormal,
536  Entity::TileMode::kDecal),
537  });
538  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
539 }

References impeller::Color::Black(), impeller::Canvas::DrawImage(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), FLT_FORWARD, impeller::Entity::kDecal, impeller::kMetal, impeller::FilterContents::kNormal, impeller::ImageFilter::MakeBlur(), and impeller::Canvas::Scale().

◆ TEST_P() [165/419]

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

Definition at line 654 of file aiks_gradient_unittests.cc.

654  {
655  // Compare with https://fiddle.skia.org/c/027392122bec8ac2b5d5de00a4b9bbe2
656  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
657  static float scale = 3;
658  static bool add_circle_clip = true;
659  const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
660  const Entity::TileMode tile_modes[] = {
661  Entity::TileMode::kClamp, Entity::TileMode::kRepeat,
662  Entity::TileMode::kMirror, Entity::TileMode::kDecal};
663  static int selected_tile_mode = 0;
664  static float alpha = 1;
665 
666  if (AiksTest::ImGuiBegin("Controls", nullptr,
667  ImGuiWindowFlags_AlwaysAutoResize)) {
668  ImGui::SliderFloat("Scale", &scale, 0, 6);
669  ImGui::Checkbox("Circle clip", &add_circle_clip);
670  ImGui::SliderFloat("Alpha", &alpha, 0, 1);
671  ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
672  sizeof(tile_mode_names) / sizeof(char*));
673  ImGui::End();
674  }
675 
676  Canvas canvas;
677  canvas.Scale(GetContentScale());
678  Paint paint;
679  paint.color = Color::White();
680  canvas.DrawPaint(paint);
681 
682  paint.style = Paint::Style::kStroke;
683  paint.color = Color(1.0, 1.0, 1.0, alpha);
684  paint.stroke_width = 10;
685  auto tile_mode = tile_modes[selected_tile_mode];
686 
687  std::vector<Color> colors = {Color{0.9568, 0.2627, 0.2118, 1.0},
688  Color{0.1294, 0.5882, 0.9529, 1.0}};
689  std::vector<Scalar> stops = {0.0, 1.0};
690 
691  paint.color_source = ColorSource::MakeLinearGradient(
692  {0, 0}, {50, 50}, std::move(colors), std::move(stops), tile_mode, {});
693 
694  Path path = PathBuilder{}
695  .MoveTo({20, 20})
696  .QuadraticCurveTo({60, 20}, {60, 60})
697  .Close()
698  .MoveTo({60, 20})
699  .QuadraticCurveTo({60, 60}, {20, 60})
700  .TakePath();
701 
702  canvas.Scale(Vector2(scale, scale));
703 
704  if (add_circle_clip) {
705  static PlaygroundPoint circle_clip_point_a(Point(60, 300), 20,
706  Color::Red());
707  static PlaygroundPoint circle_clip_point_b(Point(600, 300), 20,
708  Color::Red());
709  auto [handle_a, handle_b] =
710  DrawPlaygroundLine(circle_clip_point_a, circle_clip_point_b);
711 
712  auto screen_to_canvas = canvas.GetCurrentTransform().Invert();
713  Point point_a = screen_to_canvas * handle_a * GetContentScale();
714  Point point_b = screen_to_canvas * handle_b * GetContentScale();
715 
716  Point middle = (point_a + point_b) / 2;
717  auto radius = point_a.GetDistance(middle);
718  canvas.ClipPath(PathBuilder{}.AddCircle(middle, radius).TakePath());
719  }
720 
721  for (auto join : {Join::kBevel, Join::kRound, Join::kMiter}) {
722  paint.stroke_join = join;
723  for (auto cap : {Cap::kButt, Cap::kSquare, Cap::kRound}) {
724  paint.stroke_cap = cap;
725  canvas.DrawPath(path, paint);
726  canvas.Translate({80, 0});
727  }
728  canvas.Translate({-240, 60});
729  }
730 
731  return canvas.EndRecordingAsPicture();
732  };
733 
734  ASSERT_TRUE(OpenPlaygroundHere(callback));
735 }

References impeller::PathBuilder::AddCircle(), impeller::Canvas::ClipPath(), impeller::Close(), impeller::Paint::color, impeller::Paint::color_source, impeller::Canvas::DrawPaint(), impeller::Canvas::DrawPath(), impeller::DrawPlaygroundLine(), impeller::Canvas::EndRecordingAsPicture(), impeller::Canvas::GetCurrentTransform(), impeller::TPoint< T >::GetDistance(), impeller::AiksPlayground::ImGuiBegin(), impeller::Matrix::Invert(), impeller::kBevel, impeller::kButt, impeller::Entity::kClamp, impeller::Entity::kDecal, impeller::Entity::kMirror, impeller::kMiter, impeller::Entity::kRepeat, impeller::kRound, impeller::kSquare, impeller::Paint::kStroke, impeller::ColorSource::MakeLinearGradient(), impeller::PathBuilder::MoveTo(), impeller::Color::Red(), impeller::Canvas::Scale(), 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::White().

◆ TEST_P() [166/419]

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

Definition at line 967 of file aiks_blur_unittests.cc.

967  {
968  // This makes sure if mip maps are recycled across invocations of blurs the
969  // contents get updated each frame correctly. If they aren't updated the color
970  // inside the blur and outside the blur will be different.
971  //
972  // If there is some change to render target caching this could display a false
973  // positive in the future. Also, if the LOD that is rendered is 1 it could
974  // present a false positive.
975  int32_t count = 0;
976  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
977  Canvas canvas;
978  if (count++ == 0) {
979  canvas.DrawCircle({100, 100}, 50, {.color = Color::CornflowerBlue()});
980  } else {
981  canvas.DrawCircle({100, 100}, 50, {.color = Color::Chartreuse()});
982  }
983  canvas.ClipRRect(Rect::MakeLTRB(75, 50, 375, 275), {20, 20});
984  canvas.SaveLayer({.blend_mode = BlendMode::kSource}, std::nullopt,
985  ImageFilter::MakeBlur(Sigma(30.0), Sigma(30.0),
986  FilterContents::BlurStyle::kNormal,
987  Entity::TileMode::kClamp));
988  canvas.Restore();
989  return canvas.EndRecordingAsPicture();
990  };
991 
992  ASSERT_TRUE(OpenPlaygroundHere(callback));
993 }

References impeller::Color::Chartreuse(), impeller::Canvas::ClipRRect(), impeller::Color::CornflowerBlue(), impeller::Canvas::DrawCircle(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kClamp, impeller::FilterContents::kNormal, impeller::kSource, impeller::ImageFilter::MakeBlur(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Canvas::Restore(), and impeller::Canvas::SaveLayer().

◆ TEST_P() [167/419]

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

Definition at line 3287 of file aiks_unittests.cc.

3287  {
3288  // Compare with https://fiddle.skia.org/c/6cdc5aefb291fda3833b806ca347a885
3289 
3290  Canvas canvas;
3291  auto texture = CreateTextureForFixture("monkey.png");
3292 
3293  canvas.DrawPaint({.color = Color::White()});
3294 
3295  // Translation
3296  {
3297  Paint paint;
3298  paint.color_source = ColorSource::MakeImage(
3299  texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {},
3300  Matrix::MakeTranslation({50, 50}));
3301  canvas.DrawRect(Rect::MakeLTRB(0, 0, 100, 100), paint);
3302  }
3303 
3304  // Rotation/skew
3305  {
3306  canvas.Save();
3307  canvas.Rotate(Degrees(45));
3308  Paint paint;
3309  paint.color_source = ColorSource::MakeImage(
3310  texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {},
3311  Matrix(1, -1, 0, 0, //
3312  1, 1, 0, 0, //
3313  0, 0, 1, 0, //
3314  0, 0, 0, 1) //
3315  );
3316  canvas.DrawRect(Rect::MakeLTRB(100, 0, 200, 100), paint);
3317  canvas.Restore();
3318  }
3319 
3320  // Scale
3321  {
3322  canvas.Translate(Vector2(100, 0));
3323  canvas.Scale(Vector2(100, 100));
3324  Paint paint;
3325  paint.color_source = ColorSource::MakeImage(
3326  texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {},
3327  Matrix::MakeScale(Vector2(0.005, 0.005)));
3328  canvas.DrawRect(Rect::MakeLTRB(0, 0, 1, 1), paint);
3329  }
3330 
3331  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3332 }

References impeller::Paint::color_source, impeller::Canvas::DrawPaint(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kRepeat, impeller::ColorSource::MakeImage(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::Canvas::Restore(), impeller::Canvas::Rotate(), impeller::Canvas::Save(), impeller::Canvas::Scale(), impeller::Canvas::Translate(), and impeller::Color::White().

◆ TEST_P() [168/419]

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

Definition at line 2419 of file aiks_unittests.cc.

2419  {
2420  Canvas canvas;
2421  canvas.Scale(GetContentScale());
2422 
2423  auto test = [&canvas](const std::shared_ptr<ImageFilter>& filter) {
2424  auto DrawLine = [&canvas](const Point& p0, const Point& p1,
2425  const Paint& p) {
2426  auto path = PathBuilder{}
2427  .AddLine(p0, p1)
2428  .SetConvexity(Convexity::kConvex)
2429  .TakePath();
2430  Paint paint = p;
2431  paint.style = Paint::Style::kStroke;
2432  canvas.DrawPath(path, paint);
2433  };
2434  // Registration marks for the edge of the SaveLayer
2435  DrawLine(Point(75, 100), Point(225, 100), {.color = Color::White()});
2436  DrawLine(Point(75, 200), Point(225, 200), {.color = Color::White()});
2437  DrawLine(Point(100, 75), Point(100, 225), {.color = Color::White()});
2438  DrawLine(Point(200, 75), Point(200, 225), {.color = Color::White()});
2439 
2440  canvas.SaveLayer({.image_filter = filter},
2441  Rect::MakeLTRB(100, 100, 200, 200));
2442  {
2443  // DrawPaint to verify correct behavior when the contents are unbounded.
2444  canvas.DrawPaint({.color = Color::Yellow()});
2445 
2446  // Contrasting rectangle to see interior blurring
2447  canvas.DrawRect(Rect::MakeLTRB(125, 125, 175, 175),
2448  {.color = Color::Blue()});
2449  }
2450  canvas.Restore();
2451  };
2452 
2453  test(ImageFilter::MakeBlur(Sigma{10.0}, Sigma{10.0},
2454  FilterContents::BlurStyle::kNormal,
2455  Entity::TileMode::kDecal));
2456 
2457  canvas.Translate({200.0, 0.0});
2458 
2459  test(ImageFilter::MakeDilate(Radius{10.0}, Radius{10.0}));
2460 
2461  canvas.Translate({200.0, 0.0});
2462 
2463  test(ImageFilter::MakeErode(Radius{10.0}, Radius{10.0}));
2464 
2465  canvas.Translate({-400.0, 200.0});
2466 
2467  auto rotate_filter =
2468  ImageFilter::MakeMatrix(Matrix::MakeTranslation({150, 150}) *
2469  Matrix::MakeRotationZ(Degrees{10.0}) *
2470  Matrix::MakeTranslation({-150, -150}),
2471  SamplerDescriptor{});
2472  test(rotate_filter);
2473 
2474  canvas.Translate({200.0, 0.0});
2475 
2476  auto rgb_swap_filter = ImageFilter::MakeFromColorFilter(
2477  *ColorFilter::MakeMatrix({.array = {
2478  0, 1, 0, 0, 0, //
2479  0, 0, 1, 0, 0, //
2480  1, 0, 0, 0, 0, //
2481  0, 0, 0, 1, 0 //
2482  }}));
2483  test(rgb_swap_filter);
2484 
2485  canvas.Translate({200.0, 0.0});
2486 
2487  test(ImageFilter::MakeCompose(*rotate_filter, *rgb_swap_filter));
2488 
2489  canvas.Translate({-400.0, 200.0});
2490 
2491  test(ImageFilter::MakeLocalMatrix(Matrix::MakeTranslation({25.0, 25.0}),
2492  *rotate_filter));
2493 
2494  canvas.Translate({200.0, 0.0});
2495 
2496  test(ImageFilter::MakeLocalMatrix(Matrix::MakeTranslation({25.0, 25.0}),
2497  *rgb_swap_filter));
2498 
2499  canvas.Translate({200.0, 0.0});
2500 
2501  test(ImageFilter::MakeLocalMatrix(
2502  Matrix::MakeTranslation({25.0, 25.0}),
2503  *ImageFilter::MakeCompose(*rotate_filter, *rgb_swap_filter)));
2504 
2505  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2506 }

References impeller::PathBuilder::AddLine(), impeller::Color::Blue(), impeller::Canvas::DrawPaint(), impeller::Canvas::DrawPath(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::kConvex, impeller::Entity::kDecal, impeller::FilterContents::kNormal, impeller::Paint::kStroke, impeller::ImageFilter::MakeBlur(), impeller::ImageFilter::MakeCompose(), impeller::ImageFilter::MakeDilate(), impeller::ImageFilter::MakeErode(), impeller::ImageFilter::MakeFromColorFilter(), impeller::ImageFilter::MakeLocalMatrix(), impeller::TRect< Scalar >::MakeLTRB(), impeller::ColorFilter::MakeMatrix(), impeller::ImageFilter::MakeMatrix(), impeller::Matrix::MakeRotationZ(), impeller::Matrix::MakeTranslation(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), impeller::Canvas::Scale(), impeller::PathBuilder::SetConvexity(), impeller::Paint::style, impeller::PathBuilder::TakePath(), impeller::Canvas::Translate(), impeller::Color::White(), and impeller::Color::Yellow().

◆ TEST_P() [169/419]

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

Definition at line 2508 of file aiks_unittests.cc.

2508  {
2509  Canvas canvas;
2510  canvas.Scale(GetContentScale());
2511 
2512  auto blur_filter = ImageFilter::MakeBlur(Sigma{10.0}, Sigma{10.0},
2513  FilterContents::BlurStyle::kNormal,
2514  Entity::TileMode::kDecal);
2515 
2516  canvas.SaveLayer({.image_filter = blur_filter}, std::nullopt);
2517  {
2518  // DrawPaint to verify correct behavior when the contents are unbounded.
2519  canvas.DrawPaint({.color = Color::Yellow()});
2520 
2521  // Contrasting rectangle to see interior blurring
2522  canvas.DrawRect(Rect::MakeLTRB(125, 125, 175, 175),
2523  {.color = Color::Blue()});
2524  }
2525  canvas.Restore();
2526 
2527  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2528 }

References impeller::Color::Blue(), impeller::Canvas::DrawPaint(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kDecal, impeller::FilterContents::kNormal, impeller::ImageFilter::MakeBlur(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), impeller::Canvas::Scale(), and impeller::Color::Yellow().

◆ TEST_P() [170/419]

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

Definition at line 2205 of file aiks_unittests.cc.

2205  {
2206  Canvas canvas;
2207 
2208  canvas.SaveLayer({
2209  .color_filter = ColorFilter::MakeLinearToSrgb(),
2210  });
2211 
2212  canvas.Translate({500, 300, 0});
2213  canvas.Rotate(Radians(2 * kPi / 3));
2214  canvas.DrawRect(Rect::MakeXYWH(100, 100, 200, 200), {.color = Color::Blue()});
2215 
2216  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2217 }

References impeller::Color::Blue(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::kPi, impeller::ColorFilter::MakeLinearToSrgb(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Canvas::Rotate(), impeller::Canvas::SaveLayer(), and impeller::Canvas::Translate().

◆ TEST_P() [171/419]

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

Definition at line 1149 of file aiks_blur_unittests.cc.

1149  {
1150  Scalar sigma = 70;
1151  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
1152  if (AiksTest::ImGuiBegin("Controls", nullptr,
1153  ImGuiWindowFlags_AlwaysAutoResize)) {
1154  ImGui::SliderFloat("Sigma", &sigma, 0, 500);
1155  ImGui::End();
1156  }
1157  Canvas canvas;
1158  canvas.Scale(GetContentScale());
1159  canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
1160 
1161  std::shared_ptr<Texture> boston = CreateTextureForFixture("boston.jpg");
1162  ColorSource image_source = ColorSource::MakeImage(
1163  boston, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {}, {});
1164 
1165  canvas.Transform(Matrix::MakeTranslation({100, 100, 0}) *
1166  Matrix::MakeScale({0.5, 0.5, 1.0}));
1167  Paint paint = {
1168  .color_source = image_source,
1169  .mask_blur_descriptor =
1170  Paint::MaskBlurDescriptor{
1171  .style = FilterContents::BlurStyle::kNormal,
1172  .sigma = Sigma(sigma),
1173  },
1174  };
1175  canvas.DrawRect(
1176  Rect::MakeXYWH(0, 0, boston->GetSize().width, boston->GetSize().height),
1177  paint);
1178 
1179  return canvas.EndRecordingAsPicture();
1180  };
1181  ASSERT_TRUE(OpenPlaygroundHere(callback));
1182 }

References impeller::Paint::color_source, impeller::Canvas::DrawPaint(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::AiksPlayground::ImGuiBegin(), impeller::FilterContents::kNormal, impeller::Entity::kRepeat, impeller::ColorSource::MakeImage(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Canvas::Scale(), impeller::Paint::MaskBlurDescriptor::style, and impeller::Canvas::Transform().

◆ TEST_P() [172/419]

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

Definition at line 941 of file aiks_blur_unittests.cc.

941  {
942  Scalar sigma = 30;
943  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
944  if (AiksTest::ImGuiBegin("Controls", nullptr,
945  ImGuiWindowFlags_AlwaysAutoResize)) {
946  ImGui::SliderFloat("Sigma", &sigma, 0, 500);
947  ImGui::End();
948  }
949  Canvas canvas;
950  canvas.Scale(GetContentScale());
951  Paint paint;
952  paint.color = Color::Green();
953  paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
954  .style = FilterContents::BlurStyle::kNormal,
955  .sigma = Sigma(sigma),
956  };
957  std::shared_ptr<Texture> boston = CreateTextureForFixture("boston.jpg");
958  canvas.DrawImage(std::make_shared<Image>(boston), {200, 200}, paint);
959  Paint red;
960  red.color = Color::Red();
961  canvas.DrawRect(Rect::MakeXYWH(0, 0, 200, 200), red);
962  return canvas.EndRecordingAsPicture();
963  };
964  ASSERT_TRUE(OpenPlaygroundHere(callback));
965 }

References impeller::Paint::color, impeller::Canvas::DrawImage(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::AiksPlayground::ImGuiBegin(), impeller::FilterContents::kNormal, impeller::TRect< Scalar >::MakeXYWH(), impeller::Paint::mask_blur_descriptor, impeller::Color::Red(), impeller::Canvas::Scale(), and impeller::Paint::MaskBlurDescriptor::style.

◆ TEST_P() [173/419]

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

Definition at line 267 of file aiks_blur_unittests.cc.

267  {
268  Canvas canvas;
269 
270  Paint paint = {
271  .color = Color::Blue(),
272  .mask_blur_descriptor =
273  Paint::MaskBlurDescriptor{
274  .style = FilterContents::BlurStyle::kNormal,
275  .sigma = Sigma(0),
276  },
277  };
278 
279  canvas.DrawCircle({300, 300}, 200, paint);
280  canvas.DrawRect(Rect::MakeLTRB(100, 300, 500, 600), paint);
281 
282  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
283 }

References impeller::Color::Blue(), impeller::Paint::color, impeller::Canvas::DrawCircle(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::FilterContents::kNormal, impeller::TRect< Scalar >::MakeLTRB(), and impeller::Paint::MaskBlurDescriptor::style.

◆ TEST_P() [174/419]

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

Definition at line 2963 of file aiks_unittests.cc.

2963  {
2964  Canvas canvas;
2965  canvas.DrawPaint({.color = Color::Black()});
2966  canvas.SaveLayer({}, std::nullopt);
2967  {
2968  canvas.DrawCircle(Point(200, 200), 100,
2969  {.color = Color::Green().WithAlpha(0.5),
2970  .blend_mode = BlendMode::kPlus});
2971  // Should render a second circle, centered on the bottom-right-most edge of
2972  // the circle.
2973  canvas.SaveLayer(
2974  {}, std::nullopt,
2975  ImageFilter::MakeMatrix(
2976  Matrix::MakeTranslation(Vector2(1, 1) * (100 + 100 * k1OverSqrt2)) *
2977  Matrix::MakeScale(Vector2(1, 1) * 0.5) *
2978  Matrix::MakeTranslation(Vector2(-100, -100)),
2979  SamplerDescriptor{}));
2980  canvas.Restore();
2981  }
2982  canvas.Restore();
2983 
2984  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2985 }

References impeller::Color::Black(), impeller::Canvas::DrawCircle(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::k1OverSqrt2, impeller::kPlus, impeller::ImageFilter::MakeMatrix(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Color::WithAlpha().

◆ TEST_P() [175/419]

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

Definition at line 3206 of file aiks_unittests.cc.

3207  {
3208  Canvas canvas;
3209  canvas.Scale(GetContentScale());
3210  canvas.Translate({100, 100});
3211  // Draw a circle in a SaveLayer at -300, but move it back on-screen with a
3212  // +300 translation applied by a SaveLayer image filter.
3213  canvas.SaveLayer({
3214  .image_filter = std::make_shared<MatrixImageFilter>(
3215  Matrix::MakeTranslation({300, 0}) * Matrix::MakeScale({2, 2, 2}),
3216  SamplerDescriptor{}),
3217  });
3218  canvas.DrawCircle({-150, 0}, 50, {.color = Color::Green()});
3219  canvas.Restore();
3220 
3221  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3222 }

References impeller::Canvas::DrawCircle(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), impeller::Canvas::Scale(), and impeller::Canvas::Translate().

◆ TEST_P() [176/419]

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

Definition at line 3189 of file aiks_unittests.cc.

3189  {
3190  Canvas canvas;
3191  canvas.Scale(GetContentScale());
3192  canvas.Translate({100, 100});
3193  // Draw a circle in a SaveLayer at -300, but move it back on-screen with a
3194  // +300 translation applied by a SaveLayer image filter.
3195  canvas.SaveLayer({
3196  .image_filter = std::make_shared<MatrixImageFilter>(
3197  Matrix::MakeTranslation({300, 0}), SamplerDescriptor{}),
3198  });
3199  canvas.DrawCircle({-300, 0}, 100, {.color = Color::Green()});
3200  canvas.Restore();
3201 
3202  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3203 }

References impeller::Canvas::DrawCircle(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::Matrix::MakeTranslation(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), impeller::Canvas::Scale(), and impeller::Canvas::Translate().

◆ TEST_P() [177/419]

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

Definition at line 3172 of file aiks_unittests.cc.

3172  {
3173  Canvas canvas;
3174  canvas.Scale(GetContentScale());
3175  auto image = std::make_shared<Image>(CreateTextureForFixture("airplane.jpg"));
3176  canvas.Translate({600, -200});
3177  canvas.SaveLayer({
3178  .image_filter = std::make_shared<MatrixImageFilter>(
3179  Matrix::MakeScale({2, 2, 2}), SamplerDescriptor{}),
3180  });
3181  canvas.DrawImage(image, {0, 0},
3182  Paint{.color = Color::White().WithAlpha(0.5)});
3183  canvas.Restore();
3184 
3185  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3186 }

References impeller::Paint::color, impeller::Canvas::DrawImage(), impeller::Canvas::EndRecordingAsPicture(), impeller::Matrix::MakeScale(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), impeller::Canvas::Scale(), impeller::Canvas::Translate(), impeller::Color::White(), and impeller::Color::WithAlpha().

◆ TEST_P() [178/419]

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

Definition at line 2936 of file aiks_unittests.cc.

2936  {
2937  Canvas canvas;
2938  canvas.DrawPaint({.color = Color::Black()});
2939  canvas.SaveLayer({}, std::nullopt);
2940  {
2941  canvas.DrawCircle(Point(200, 200), 100,
2942  {.color = Color::Green().WithAlpha(0.5),
2943  .blend_mode = BlendMode::kPlus});
2944  // Should render a second circle, centered on the bottom-right-most edge of
2945  // the circle.
2946  canvas.SaveLayer({.image_filter = ImageFilter::MakeMatrix(
2947  Matrix::MakeTranslation(Vector2(1, 1) *
2948  (200 + 100 * k1OverSqrt2)) *
2949  Matrix::MakeScale(Vector2(1, 1) * 0.5) *
2950  Matrix::MakeTranslation(Vector2(-200, -200)),
2951  SamplerDescriptor{})},
2952  std::nullopt);
2953  canvas.DrawCircle(Point(200, 200), 100,
2954  {.color = Color::Green().WithAlpha(0.5),
2955  .blend_mode = BlendMode::kPlus});
2956  canvas.Restore();
2957  }
2958  canvas.Restore();
2959 
2960  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2961 }

References impeller::Color::Black(), impeller::Canvas::DrawCircle(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::k1OverSqrt2, impeller::kPlus, impeller::ImageFilter::MakeMatrix(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Color::WithAlpha().

◆ TEST_P() [179/419]

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

Definition at line 1925 of file aiks_unittests.cc.

1925  {
1926  auto entity_pass = std::make_shared<EntityPass>();
1927  auto rect = Rect::MakeLTRB(0, 0, 100, 100);
1928  Paint paint;
1929  paint.color = Color::White().WithAlpha(0.5);
1930  paint.color_filter =
1931  ColorFilter::MakeBlend(BlendMode::kSourceOver, Color::Blue());
1932 
1933  // Paint has color filter, can't elide.
1934  auto delegate = std::make_shared<OpacityPeepholePassDelegate>(paint);
1935  ASSERT_FALSE(delegate->CanCollapseIntoParentPass(entity_pass.get()));
1936 
1937  paint.color_filter = nullptr;
1938  paint.image_filter = ImageFilter::MakeBlur(Sigma(1.0), Sigma(1.0),
1939  FilterContents::BlurStyle::kNormal,
1940  Entity::TileMode::kClamp);
1941 
1942  // Paint has image filter, can't elide.
1943  delegate = std::make_shared<OpacityPeepholePassDelegate>(paint);
1944  ASSERT_FALSE(delegate->CanCollapseIntoParentPass(entity_pass.get()));
1945 
1946  paint.image_filter = nullptr;
1947  paint.color = Color::Red();
1948 
1949  // Paint has no alpha, can't elide;
1950  delegate = std::make_shared<OpacityPeepholePassDelegate>(paint);
1951  ASSERT_FALSE(delegate->CanCollapseIntoParentPass(entity_pass.get()));
1952 
1953  // Positive test.
1954  Entity entity;
1955  entity.SetContents(SolidColorContents::Make(
1956  PathBuilder{}.AddRect(rect).TakePath(), Color::Red()));
1957  entity_pass->AddEntity(std::move(entity));
1958  paint.color = Color::Red().WithAlpha(0.5);
1959 
1960  delegate = std::make_shared<OpacityPeepholePassDelegate>(paint);
1961  ASSERT_TRUE(delegate->CanCollapseIntoParentPass(entity_pass.get()));
1962 }

References impeller::PathBuilder::AddRect(), impeller::Color::Blue(), impeller::Paint::color, impeller::Paint::color_filter, impeller::Paint::image_filter, impeller::Entity::kClamp, impeller::FilterContents::kNormal, impeller::kSourceOver, impeller::SolidColorContents::Make(), impeller::ColorFilter::MakeBlend(), impeller::ImageFilter::MakeBlur(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Color::Red(), impeller::Entity::SetContents(), impeller::Color::White(), and impeller::Color::WithAlpha().

◆ TEST_P() [180/419]

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

Definition at line 2670 of file aiks_unittests.cc.

2670  {
2671  Canvas canvas;
2672  canvas.Scale(Vector2(1.618, 1.618));
2673  canvas.DrawCircle(Point(), 10,
2674  {
2675  .color = Color::CornflowerBlue(),
2676  .blend_mode = BlendMode::kSourceOver,
2677  });
2678  Picture picture = canvas.EndRecordingAsPicture();
2679 
2680  // Extract the SolidColorSource.
2681  // Entity entity;
2682  std::vector<Entity> entity;
2683  std::shared_ptr<SolidColorContents> contents;
2684  picture.pass->IterateAllEntities([e = &entity, &contents](Entity& entity) {
2685  if (ScalarNearlyEqual(entity.GetTransform().GetScale().x, 1.618f)) {
2686  contents =
2687  std::static_pointer_cast<SolidColorContents>(entity.GetContents());
2688  e->emplace_back(entity.Clone());
2689  return false;
2690  }
2691  return true;
2692  });
2693 
2694  ASSERT_TRUE(entity.size() >= 1);
2695  ASSERT_TRUE(contents->IsOpaque());
2696  ASSERT_EQ(entity[0].GetBlendMode(), BlendMode::kSource);
2697 }

References impeller::Entity::Clone(), impeller::Color::CornflowerBlue(), impeller::Canvas::DrawCircle(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::GetContents(), impeller::Matrix::GetScale(), impeller::Entity::GetTransform(), impeller::kSource, impeller::kSourceOver, impeller::Picture::pass, impeller::ScalarNearlyEqual(), impeller::Canvas::Scale(), and impeller::Vector3::x.

◆ TEST_P() [181/419]

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

Definition at line 1086 of file aiks_unittests.cc.

1086  {
1087  Paint paint;
1088  Canvas canvas;
1089  // Default is kSourceOver.
1090  paint.color = Color(1, 0, 0, 0.5);
1091  canvas.DrawCircle(Point(150, 200), 100, paint);
1092  paint.color = Color(0, 1, 0, 0.5);
1093  canvas.DrawCircle(Point(250, 200), 100, paint);
1094 
1095  paint.blend_mode = BlendMode::kPlus;
1096  paint.color = Color::Red();
1097  canvas.DrawCircle(Point(450, 250), 100, paint);
1098  paint.color = Color::Green();
1099  canvas.DrawCircle(Point(550, 250), 100, paint);
1100  paint.color = Color::Blue();
1101  canvas.DrawCircle(Point(500, 150), 100, paint);
1102  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1103 }

References impeller::Paint::blend_mode, impeller::Color::Blue(), impeller::Paint::color, impeller::Canvas::DrawCircle(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::kPlus, and impeller::Color::Red().

◆ TEST_P() [182/419]

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

Definition at line 1898 of file aiks_unittests.cc.

1898  {
1899  // validate that a paint with a color filter "HasFilters", no other filters
1900  // impact this setting.
1901  Paint paint;
1902 
1903  ASSERT_FALSE(paint.HasColorFilter());
1904 
1905  paint.color_filter =
1906  ColorFilter::MakeBlend(BlendMode::kSourceOver, Color::Blue());
1907 
1908  ASSERT_TRUE(paint.HasColorFilter());
1909 
1910  paint.image_filter = ImageFilter::MakeBlur(Sigma(1.0), Sigma(1.0),
1911  FilterContents::BlurStyle::kNormal,
1912  Entity::TileMode::kClamp);
1913 
1914  ASSERT_TRUE(paint.HasColorFilter());
1915 
1916  paint.mask_blur_descriptor = {};
1917 
1918  ASSERT_TRUE(paint.HasColorFilter());
1919 
1920  paint.color_filter = nullptr;
1921 
1922  ASSERT_FALSE(paint.HasColorFilter());
1923 }

References impeller::Color::Blue(), impeller::Paint::color_filter, impeller::Paint::HasColorFilter(), impeller::Paint::image_filter, impeller::Entity::kClamp, impeller::FilterContents::kNormal, impeller::kSourceOver, impeller::ColorFilter::MakeBlend(), impeller::ImageFilter::MakeBlur(), and impeller::Paint::mask_blur_descriptor.

◆ TEST_P() [183/419]

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

Definition at line 1988 of file aiks_unittests.cc.

1989  {
1990  Canvas canvas;
1991  canvas.SaveLayer({}, std::nullopt, ImageFilter::MakeMatrix(Matrix(), {}));
1992  canvas.DrawPaint({.color = Color::Red(), .blend_mode = BlendMode::kSource});
1993  canvas.DrawPaint({.color = Color::CornflowerBlue().WithAlpha(0.75),
1994  .blend_mode = BlendMode::kSourceOver});
1995  canvas.Restore();
1996 
1997  Picture picture = canvas.EndRecordingAsPicture();
1998 
1999  std::shared_ptr<ContextSpy> spy = ContextSpy::Make();
2000  std::shared_ptr<Context> real_context = GetContext();
2001  std::shared_ptr<ContextMock> mock_context = spy->MakeContext(real_context);
2002  AiksContext renderer(mock_context, nullptr);
2003  std::shared_ptr<Image> image = picture.ToImage(renderer, {300, 300});
2004 
2005  ASSERT_EQ(spy->render_passes_.size(),
2006  GetBackend() == PlaygroundBackend::kOpenGLES ? 4llu : 3llu);
2007  std::shared_ptr<RenderPass> render_pass = spy->render_passes_[0];
2008  ASSERT_EQ(render_pass->GetCommands().size(), 0llu);
2009 }

References impeller::Color::CornflowerBlue(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::kOpenGLES, impeller::kSource, impeller::kSourceOver, impeller::ImageFilter::MakeMatrix(), impeller::Color::Red(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), impeller::Picture::ToImage(), and impeller::Color::WithAlpha().

◆ TEST_P() [184/419]

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

Definition at line 3027 of file aiks_unittests.cc.

3027  {
3028  Canvas canvas;
3029 
3030  // Should render a green square in the middle of a blue circle.
3031  canvas.SaveLayer({});
3032  {
3033  canvas.Translate(Point(100, 100));
3034  canvas.DrawCircle(Point(200, 200), 200, {.color = Color::Blue()});
3035  canvas.ClipRect(Rect::MakeXYWH(100, 100, 200, 200));
3036  canvas.DrawCircle(Point(200, 200), 200,
3037  {
3038  .color = Color::Green(),
3039  .blend_mode = BlendMode::kSourceOver,
3040  .image_filter = ImageFilter::MakeFromColorFilter(
3041  *ColorFilter::MakeBlend(BlendMode::kDestination,
3042  Color::White())),
3043  });
3044  canvas.Restore();
3045  }
3046 
3047  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3048 }

References impeller::Color::Blue(), impeller::Canvas::ClipRect(), impeller::Canvas::DrawCircle(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::kDestination, impeller::kSourceOver, impeller::ColorFilter::MakeBlend(), impeller::ImageFilter::MakeFromColorFilter(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), impeller::Canvas::Translate(), and impeller::Color::White().

◆ TEST_P() [185/419]

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

Definition at line 3083 of file aiks_unittests.cc.

3083  {
3084  auto context = MakeContext();
3085  std::weak_ptr<Texture> weak_texture;
3086 
3087  {
3088  auto texture = CreateTextureForFixture("table_mountain_nx.png");
3089 
3090  Canvas canvas;
3091  canvas.Scale(GetContentScale());
3092  canvas.Translate({100.0f, 100.0f, 0});
3093 
3094  Paint paint;
3095  paint.color_source = ColorSource::MakeImage(
3096  texture, Entity::TileMode::kClamp, Entity::TileMode::kClamp, {}, {});
3097  canvas.DrawRect(Rect::MakeXYWH(0, 0, 600, 600), paint);
3098 
3099  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3100  }
3101 
3102  // See https://github.com/flutter/flutter/issues/134751.
3103  //
3104  // If the fence waiter was working this may not be released by the end of the
3105  // scope above. Adding a manual shutdown so that future changes to the fence
3106  // waiter will not flake this test.
3107  context->Shutdown();
3108 
3109  // The texture should be released by now.
3110  ASSERT_TRUE(weak_texture.expired()) << "When the texture is no longer in use "
3111  "by the backend, it should be "
3112  "released.";
3113 }

References impeller::Paint::color_source, impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kClamp, impeller::ColorSource::MakeImage(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Canvas::Scale(), and impeller::Canvas::Translate().

◆ TEST_P() [186/419]

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

Definition at line 20 of file aiks_path_unittests.cc.

20  {
21  Canvas canvas;
22  canvas.Concat(Matrix::MakeTranslation({300, 300}));
23  canvas.Concat(Matrix::MakeRotationZ(Radians(kPiOver2)));
24  auto arrow_stem =
25  PathBuilder{}.MoveTo({120, 190}).LineTo({120, 50}).TakePath();
26  auto arrow_head = PathBuilder{}
27  .MoveTo({50, 120})
28  .LineTo({120, 190})
29  .LineTo({190, 120})
30  .TakePath();
31  auto paint = Paint{
32  .stroke_width = 15.0,
33  .stroke_cap = Cap::kRound,
34  .stroke_join = Join::kRound,
35  .style = Paint::Style::kStroke,
36  .color_filter =
37  ColorFilter::MakeBlend(BlendMode::kSourceIn, Color::AliceBlue()),
38  };
39 
40  canvas.DrawPath(arrow_stem, paint);
41  canvas.DrawPath(arrow_head, paint);
42  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
43 }

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

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

Definition at line 1746 of file aiks_unittests.cc.

1746  {
1747  // Compare with https://fiddle.skia.org/c/9e03de8567ffb49e7e83f53b64bcf636
1748  Canvas canvas;
1749  Paint paint;
1750 
1751  paint.color = Color::Black();
1752  Rect rect = Rect::MakeXYWH(25, 25, 25, 25);
1753  canvas.DrawRect(rect, paint);
1754 
1755  canvas.Translate({10, 10});
1756  canvas.SaveLayer({});
1757 
1758  paint.color = Color::Green();
1759  canvas.DrawRect(rect, paint);
1760 
1761  canvas.Restore();
1762 
1763  canvas.Translate({10, 10});
1764  paint.color = Color::Red();
1765  canvas.DrawRect(rect, paint);
1766 
1767  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1768 }

References impeller::Color::Black(), impeller::Paint::color, impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Color::Red(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Canvas::Translate().

◆ TEST_P() [188/419]

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

Definition at line 1827 of file aiks_unittests.cc.

1827  {
1828  Canvas canvas;
1829  canvas.Scale(GetContentScale());
1830  canvas.Translate(Vector2(100, 100));
1831 
1832  auto texture = std::make_shared<Image>(CreateTextureForFixture("boston.jpg"));
1833  auto draw_image_layer = [&canvas, &texture](const Paint& paint) {
1834  canvas.SaveLayer(paint);
1835  canvas.DrawImage(texture, {}, Paint{});
1836  canvas.Restore();
1837  };
1838 
1839  Paint effect_paint;
1840  effect_paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
1841  .style = FilterContents::BlurStyle::kNormal,
1842  .sigma = Sigma{6},
1843  };
1844  draw_image_layer(effect_paint);
1845 
1846  canvas.Translate(Vector2(300, 300));
1847  canvas.Scale(Vector2(3, 3));
1848  draw_image_layer(effect_paint);
1849 
1850  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1851 }

References impeller::Canvas::DrawImage(), impeller::Canvas::EndRecordingAsPicture(), impeller::FilterContents::kNormal, impeller::Paint::mask_blur_descriptor, impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), impeller::Canvas::Scale(), impeller::Paint::MaskBlurDescriptor::style, and impeller::Canvas::Translate().

◆ TEST_P() [189/419]

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

Definition at line 1770 of file aiks_unittests.cc.

1770  {
1771  Canvas canvas;
1772  Paint paint;
1773  Rect rect = Rect::MakeXYWH(0, 0, 1000, 1000);
1774 
1775  // Black, green, and red squares offset by [10, 10].
1776  {
1777  canvas.SaveLayer({}, Rect::MakeXYWH(25, 25, 25, 25));
1778  paint.color = Color::Black();
1779  canvas.DrawRect(rect, paint);
1780  canvas.Restore();
1781  }
1782 
1783  {
1784  canvas.SaveLayer({}, Rect::MakeXYWH(35, 35, 25, 25));
1785  paint.color = Color::Green();
1786  canvas.DrawRect(rect, paint);
1787  canvas.Restore();
1788  }
1789 
1790  {
1791  canvas.SaveLayer({}, Rect::MakeXYWH(45, 45, 25, 25));
1792  paint.color = Color::Red();
1793  canvas.DrawRect(rect, paint);
1794  canvas.Restore();
1795  }
1796 
1797  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1798 }

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

◆ TEST_P() [190/419]

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

Definition at line 2987 of file aiks_unittests.cc.

2987  {
2988  auto contents = SolidColorContents();
2989  contents.SetColor(Color::CornflowerBlue().WithAlpha(0.75));
2990  auto result = contents.ApplyColorFilter([](const Color& color) {
2991  return color.Blend(Color::LimeGreen().WithAlpha(0.75), BlendMode::kScreen);
2992  });
2993  ASSERT_TRUE(result);
2994  ASSERT_COLOR_NEAR(contents.GetColor(),
2995  Color(0.424452, 0.828743, 0.79105, 0.9375));
2996 }

References ASSERT_COLOR_NEAR, impeller::Color::Blend(), impeller::Color::CornflowerBlue(), impeller::kScreen, and impeller::Color::LimeGreen().

◆ TEST_P() [191/419]

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

Definition at line 1557 of file aiks_unittests.cc.

1557  {
1558  Canvas canvas;
1559  canvas.Scale(GetContentScale());
1560  Paint paint;
1561  paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
1562  .style = FilterContents::BlurStyle::kNormal,
1563  .sigma = Sigma{1},
1564  };
1565 
1566  canvas.DrawPaint({.color = Color::White()});
1567 
1568  paint.color = Color::Crimson();
1569  Scalar y = 100.0f;
1570  for (int i = 0; i < 5; i++) {
1571  Scalar x = (i + 1) * 100;
1572  Scalar radius = x / 10.0f;
1573  canvas.DrawRect(Rect::MakeXYWH(x + 25 - radius / 2, y + radius / 2, //
1574  radius, 60.0f - radius),
1575  paint);
1576  }
1577 
1578  paint.color = Color::Blue();
1579  y += 100.0f;
1580  for (int i = 0; i < 5; i++) {
1581  Scalar x = (i + 1) * 100;
1582  Scalar radius = x / 10.0f;
1583  canvas.DrawCircle({x + 25, y + 25}, radius, paint);
1584  }
1585 
1586  paint.color = Color::Green();
1587  y += 100.0f;
1588  for (int i = 0; i < 5; i++) {
1589  Scalar x = (i + 1) * 100;
1590  Scalar radius = x / 10.0f;
1591  canvas.DrawOval(Rect::MakeXYWH(x + 25 - radius / 2, y + radius / 2, //
1592  radius, 60.0f - radius),
1593  paint);
1594  }
1595 
1596  paint.color = Color::Purple();
1597  y += 100.0f;
1598  for (int i = 0; i < 5; i++) {
1599  Scalar x = (i + 1) * 100;
1600  Scalar radius = x / 20.0f;
1601  canvas.DrawRRect(Rect::MakeXYWH(x, y, 60.0f, 60.0f), //
1602  {radius, radius}, //
1603  paint);
1604  }
1605 
1606  paint.color = Color::Orange();
1607  y += 100.0f;
1608  for (int i = 0; i < 5; i++) {
1609  Scalar x = (i + 1) * 100;
1610  Scalar radius = x / 20.0f;
1611  canvas.DrawRRect(Rect::MakeXYWH(x, y, 60.0f, 60.0f), //
1612  {radius, 5.0f}, paint);
1613  }
1614 
1615  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1616 }

References impeller::Color::Blue(), impeller::Paint::color, impeller::Color::Crimson(), impeller::Canvas::DrawCircle(), impeller::Canvas::DrawOval(), impeller::Canvas::DrawPaint(), impeller::Canvas::DrawRect(), impeller::Canvas::DrawRRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::FilterContents::kNormal, impeller::TRect< Scalar >::MakeXYWH(), impeller::Paint::mask_blur_descriptor, impeller::Color::Orange(), impeller::Color::Purple(), impeller::Canvas::Scale(), impeller::Paint::MaskBlurDescriptor::style, and impeller::Color::White().

◆ TEST_P() [192/419]

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

Definition at line 181 of file aiks_path_unittests.cc.

181  {
182  // Compare with https://fiddle.skia.org/c/027392122bec8ac2b5d5de00a4b9bbe2
183  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
184  static Color color = Color::Black().WithAlpha(0.5);
185  static float scale = 3;
186  static bool add_circle_clip = true;
187 
188  if (AiksTest::ImGuiBegin("Controls", nullptr,
189  ImGuiWindowFlags_AlwaysAutoResize)) {
190  ImGui::ColorEdit4("Color", reinterpret_cast<float*>(&color));
191  ImGui::SliderFloat("Scale", &scale, 0, 6);
192  ImGui::Checkbox("Circle clip", &add_circle_clip);
193  ImGui::End();
194  }
195 
196  Canvas canvas;
197  canvas.Scale(GetContentScale());
198  Paint paint;
199 
200  paint.color = Color::White();
201  canvas.DrawPaint(paint);
202 
203  paint.color = color;
204  paint.style = Paint::Style::kStroke;
205  paint.stroke_width = 10;
206 
207  Path path = PathBuilder{}
208  .MoveTo({20, 20})
209  .QuadraticCurveTo({60, 20}, {60, 60})
210  .Close()
211  .MoveTo({60, 20})
212  .QuadraticCurveTo({60, 60}, {20, 60})
213  .TakePath();
214 
215  canvas.Scale(Vector2(scale, scale));
216 
217  if (add_circle_clip) {
218  static PlaygroundPoint circle_clip_point_a(Point(60, 300), 20,
219  Color::Red());
220  static PlaygroundPoint circle_clip_point_b(Point(600, 300), 20,
221  Color::Red());
222  auto [handle_a, handle_b] =
223  DrawPlaygroundLine(circle_clip_point_a, circle_clip_point_b);
224 
225  auto screen_to_canvas = canvas.GetCurrentTransform().Invert();
226  Point point_a = screen_to_canvas * handle_a * GetContentScale();
227  Point point_b = screen_to_canvas * handle_b * GetContentScale();
228 
229  Point middle = (point_a + point_b) / 2;
230  auto radius = point_a.GetDistance(middle);
231  canvas.ClipPath(PathBuilder{}.AddCircle(middle, radius).TakePath());
232  }
233 
234  for (auto join : {Join::kBevel, Join::kRound, Join::kMiter}) {
235  paint.stroke_join = join;
236  for (auto cap : {Cap::kButt, Cap::kSquare, Cap::kRound}) {
237  paint.stroke_cap = cap;
238  canvas.DrawPath(path, paint);
239  canvas.Translate({80, 0});
240  }
241  canvas.Translate({-240, 60});
242  }
243 
244  return canvas.EndRecordingAsPicture();
245  };
246 
247  ASSERT_TRUE(OpenPlaygroundHere(callback));
248 }

References impeller::PathBuilder::AddCircle(), impeller::Color::Black(), impeller::Canvas::ClipPath(), impeller::Close(), impeller::Paint::color, impeller::Canvas::DrawPaint(), impeller::Canvas::DrawPath(), impeller::DrawPlaygroundLine(), impeller::Canvas::EndRecordingAsPicture(), impeller::Canvas::GetCurrentTransform(), impeller::TPoint< T >::GetDistance(), impeller::AiksPlayground::ImGuiBegin(), impeller::Matrix::Invert(), impeller::kBevel, impeller::kButt, impeller::kMiter, impeller::kRound, impeller::kSquare, impeller::Paint::kStroke, impeller::PathBuilder::MoveTo(), impeller::Color::Red(), impeller::Canvas::Scale(), scale, impeller::Paint::stroke_cap, impeller::Paint::stroke_join, impeller::Paint::stroke_width, impeller::Paint::style, impeller::PathBuilder::TakePath(), impeller::Canvas::Translate(), impeller::Color::White(), and impeller::Color::WithAlpha().

◆ TEST_P() [193/419]

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

Definition at line 2219 of file aiks_unittests.cc.

2219  {
2220  Canvas canvas;
2221 
2222  canvas.SaveLayer({
2223  .color_filter = ColorFilter::MakeSrgbToLinear(),
2224  });
2225 
2226  canvas.Translate({500, 300, 0});
2227  canvas.Rotate(Radians(2 * kPi / 3));
2228  canvas.DrawRect(Rect::MakeXYWH(100, 100, 200, 200), {.color = Color::Blue()});
2229 
2230  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2231 }

References impeller::Color::Blue(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::kPi, impeller::ColorFilter::MakeSrgbToLinear(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Canvas::Rotate(), impeller::Canvas::SaveLayer(), and impeller::Canvas::Translate().

◆ TEST_P() [194/419]

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

Definition at line 1339 of file aiks_unittests.cc.

1339  {
1340  Canvas canvas;
1341  canvas.Scale(GetContentScale());
1342  Paint paint;
1343  const int color_count = 3;
1344  Color colors[color_count] = {
1345  Color::Blue(),
1346  Color::Green(),
1347  Color::Crimson(),
1348  };
1349 
1350  paint.color = Color::White();
1351  canvas.DrawPaint(paint);
1352 
1353  int c_index = 0;
1354 
1355  auto draw = [&paint, &colors, &c_index](Canvas& canvas, Point center,
1356  Scalar r, Scalar dr, int n) {
1357  for (int i = 0; i < n; i++) {
1358  paint.color = colors[(c_index++) % color_count];
1359  canvas.DrawCircle(center, r, paint);
1360  r += dr;
1361  }
1362  };
1363 
1364  paint.style = Paint::Style::kStroke;
1365  paint.stroke_width = 1;
1366  draw(canvas, {10, 10}, 2, 2, 14); // r = [2, 28], covers [1,29]
1367  paint.stroke_width = 5;
1368  draw(canvas, {10, 10}, 35, 10, 56); // r = [35, 585], covers [30,590]
1369 
1370  std::vector<Color> gradient_colors = {
1371  Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0},
1372  Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0},
1373  Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0},
1374  Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0},
1375  Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0},
1376  Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0},
1377  Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}};
1378  std::vector<Scalar> stops = {
1379  0.0,
1380  (1.0 / 6.0) * 1,
1381  (1.0 / 6.0) * 2,
1382  (1.0 / 6.0) * 3,
1383  (1.0 / 6.0) * 4,
1384  (1.0 / 6.0) * 5,
1385  1.0,
1386  };
1387  auto texture = CreateTextureForFixture("airplane.jpg",
1388  /*enable_mipmapping=*/true);
1389 
1390  paint.color_source = ColorSource::MakeRadialGradient(
1391  {500, 600}, 75, std::move(gradient_colors), std::move(stops),
1392  Entity::TileMode::kMirror, {});
1393  draw(canvas, {500, 600}, 5, 10, 10);
1394 
1395  paint.color_source = ColorSource::MakeImage(
1396  texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {},
1397  Matrix::MakeTranslation({700, 200}));
1398  draw(canvas, {800, 300}, 5, 10, 10);
1399 
1400  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1401 }

References impeller::Color::Blue(), impeller::Paint::color, impeller::Paint::color_source, impeller::Color::Crimson(), impeller::Canvas::DrawPaint(), impeller::Color::Green(), impeller::Entity::kMirror, impeller::Entity::kRepeat, impeller::Paint::kStroke, impeller::ColorSource::MakeImage(), impeller::ColorSource::MakeRadialGradient(), impeller::Matrix::MakeTranslation(), impeller::Canvas::Scale(), impeller::Paint::stroke_width, impeller::Paint::style, and impeller::Color::White().

◆ TEST_P() [195/419]

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

Definition at line 3265 of file aiks_unittests.cc.

3265  {
3266  Canvas canvas;
3267 
3268  // Use a non-srcOver blend mode to ensure that we don't detect this as an
3269  // opacity peephole optimization.
3270  canvas.SaveLayer(
3271  {.color = Color::Blue().WithAlpha(0.5), .blend_mode = BlendMode::kSource},
3272  Rect::MakeLTRB(0, 0, 200, 200));
3273  canvas.DrawPaint(
3274  {.color = Color::BlackTransparent(), .blend_mode = BlendMode::kSource});
3275  canvas.Restore();
3276 
3277  canvas.SaveLayer(
3278  {.color = Color::Blue(), .blend_mode = BlendMode::kDestinationOver});
3279  canvas.Restore();
3280 
3281  // This playground should appear blank on CI since we are only drawing
3282  // transparent black. If the clear color optimization is broken, the texture
3283  // will be filled with NaNs and may produce a magenta texture on macOS or iOS.
3284  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3285 }

References impeller::Color::BlackTransparent(), impeller::Color::Blue(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::kDestinationOver, impeller::kSource, impeller::TRect< Scalar >::MakeLTRB(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Color::WithAlpha().

◆ TEST_P() [196/419]

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

Definition at line 2903 of file aiks_unittests.cc.

2903  {
2904  auto mapping = flutter::testing::OpenFixtureAsSkData("Roboto-Regular.ttf");
2905  ASSERT_NE(mapping, nullptr);
2906 
2907  Scalar font_size = 100;
2908  sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
2909  SkFont sk_font(font_mgr->makeFromData(mapping), font_size);
2910 
2911  Paint text_paint;
2912  text_paint.color = Color::Blue();
2913 
2914  std::vector<Color> colors = {Color{0.9568, 0.2627, 0.2118, 1.0},
2915  Color{0.1294, 0.5882, 0.9529, 1.0}};
2916  std::vector<Scalar> stops = {
2917  0.0,
2918  1.0,
2919  };
2920  text_paint.color_source = ColorSource::MakeLinearGradient(
2921  {0, 0}, {100, 100}, std::move(colors), std::move(stops),
2922  Entity::TileMode::kRepeat, {});
2923 
2924  Canvas canvas;
2925  canvas.Translate({100, 100});
2926  canvas.Rotate(Radians(kPi / 4));
2927 
2928  auto blob = SkTextBlob::MakeFromString("Hello", sk_font);
2929  ASSERT_NE(blob, nullptr);
2930  auto frame = MakeTextFrameFromTextBlobSkia(blob);
2931  canvas.DrawTextFrame(frame, Point(), text_paint);
2932 
2933  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2934 }

References impeller::Color::Blue(), impeller::Paint::color, impeller::Paint::color_source, impeller::kPi, impeller::Entity::kRepeat, impeller::ColorSource::MakeLinearGradient(), impeller::MakeTextFrameFromTextBlobSkia(), and impeller::Canvas::Translate().

◆ TEST_P() [197/419]

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

Definition at line 801 of file aiks_unittests.cc.

801  {
802  // "Random" numbers between 0 and 1. Hardcoded to avoid flakiness in goldens.
803  std::array<Scalar, 20> phase_offsets = {
804  7.82637e-06, 0.131538, 0.755605, 0.45865, 0.532767,
805  0.218959, 0.0470446, 0.678865, 0.679296, 0.934693,
806  0.383502, 0.519416, 0.830965, 0.0345721, 0.0534616,
807  0.5297, 0.671149, 0.00769819, 0.383416, 0.0668422};
808  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
809  static float font_size = 20;
810  static float phase_variation = 0.2;
811  static float speed = 0.5;
812  static float magnitude = 100;
813  if (AiksTest::ImGuiBegin("Controls", nullptr,
814  ImGuiWindowFlags_AlwaysAutoResize)) {
815  ImGui::SliderFloat("Font size", &font_size, 5, 50);
816  ImGui::SliderFloat("Phase variation", &phase_variation, 0, 1);
817  ImGui::SliderFloat("Oscillation speed", &speed, 0, 2);
818  ImGui::SliderFloat("Oscillation magnitude", &magnitude, 0, 300);
819  ImGui::End();
820  }
821 
822  Canvas canvas;
823  canvas.Scale(GetContentScale());
824 
825  for (size_t i = 0; i < phase_offsets.size(); i++) {
826  auto position =
827  Point(200 + magnitude *
828  std::sin((-phase_offsets[i] * k2Pi * phase_variation +
829  GetSecondsElapsed() * speed)), //
830  200 + i * font_size * 1.1 //
831  );
833  GetContext(), canvas,
834  "the quick brown fox jumped over "
835  "the lazy dog!.?",
836  "Roboto-Regular.ttf",
837  {.font_size = font_size, .position = position})) {
838  return std::nullopt;
839  }
840  }
841  return canvas.EndRecordingAsPicture();
842  };
843 
844  ASSERT_TRUE(OpenPlaygroundHere(callback));
845 }

References impeller::Canvas::EndRecordingAsPicture(), impeller::AiksPlayground::ImGuiBegin(), impeller::k2Pi, RenderTextInCanvasSkia(), and impeller::Canvas::Scale().

◆ TEST_P() [198/419]

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

Definition at line 956 of file aiks_unittests.cc.

956  {
957  Canvas canvas;
958  canvas.Scale(GetContentScale());
959  canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
960 
961  canvas.Transform(Matrix(0.25, -0.3, 0, -0.002, //
962  0, 0.5, 0, 0, //
963  0, 0, 0.3, 0, //
964  100, 100, 0, 1.3));
965  ASSERT_TRUE(RenderTextInCanvasSkia(
966  GetContext(), canvas, "the quick brown fox jumped over the lazy dog!.?",
967  "Roboto-Regular.ttf"));
968 
969  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
970 }

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

◆ TEST_P() [199/419]

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

Definition at line 1241 of file aiks_unittests.cc.

1241  {
1242  Canvas canvas;
1243  ASSERT_MATRIX_NEAR(canvas.GetCurrentTransform(), Matrix());
1244 
1245  // clang-format off
1246  canvas.Translate(Vector3(100, 200));
1248  canvas.GetCurrentTransform(),
1249  Matrix( 1, 0, 0, 0,
1250  0, 1, 0, 0,
1251  0, 0, 1, 0,
1252  100, 200, 0, 1));
1253 
1254  canvas.Rotate(Radians(kPiOver2));
1256  canvas.GetCurrentTransform(),
1257  Matrix( 0, 1, 0, 0,
1258  -1, 0, 0, 0,
1259  0, 0, 1, 0,
1260  100, 200, 0, 1));
1261 
1262  canvas.Scale(Vector3(2, 3));
1264  canvas.GetCurrentTransform(),
1265  Matrix( 0, 2, 0, 0,
1266  -3, 0, 0, 0,
1267  0, 0, 0, 0,
1268  100, 200, 0, 1));
1269 
1270  canvas.Translate(Vector3(100, 200));
1272  canvas.GetCurrentTransform(),
1273  Matrix( 0, 2, 0, 0,
1274  -3, 0, 0, 0,
1275  0, 0, 0, 0,
1276  -500, 400, 0, 1));
1277  // clang-format on
1278 }

References ASSERT_MATRIX_NEAR, impeller::Canvas::GetCurrentTransform(), impeller::kPiOver2, impeller::Canvas::Rotate(), impeller::Canvas::Scale(), and impeller::Canvas::Translate().

◆ TEST_P() [200/419]

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

Definition at line 2357 of file aiks_unittests.cc.

2357  {
2358  Canvas canvas;
2359 
2360  canvas.DrawRect(Rect::MakeXYWH(100, 100, 300, 300), {.color = Color::Blue()});
2361 
2362  canvas.SaveLayer({.color = Color::Black().WithAlpha(0.5)});
2363  canvas.DrawRect(Rect::MakeXYWH(100, 500, 300, 300), {.color = Color::Blue()});
2364  canvas.Restore();
2365 
2366  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2367 }

References impeller::Color::Black(), impeller::Color::Blue(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Color::WithAlpha().

◆ TEST_P() [201/419]

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

Definition at line 2530 of file aiks_unittests.cc.

2530  {
2531  Canvas canvas;
2532 
2533  auto image = std::make_shared<Image>(CreateTextureForFixture("airplane.jpg"));
2534  canvas.DrawImage(image, {100, 100}, {});
2535 
2536  canvas.SaveLayer({.color = Color::Black().WithAlpha(0.5)});
2537  canvas.DrawImage(image, {100, 500}, {});
2538  canvas.Restore();
2539 
2540  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2541 }

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

◆ TEST_P() [202/419]

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

Definition at line 2614 of file aiks_unittests.cc.

2614  {
2615  Canvas canvas;
2616  canvas.DrawRect(Rect::MakeXYWH(0, 0, 400, 400), {.color = Color::Red()});
2617  canvas.SaveLayer({
2618  .color = Color::Black().WithAlpha(0.5),
2619  .blend_mode = BlendMode::kLighten,
2620  });
2621  canvas.DrawCircle({200, 200}, 100, {.color = Color::Green()});
2622  canvas.Restore();
2623  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2624 }

References impeller::Color::Black(), impeller::Canvas::DrawCircle(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::kLighten, impeller::TRect< Scalar >::MakeXYWH(), impeller::Color::Red(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Color::WithAlpha().

◆ TEST_P() [203/419]

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

Definition at line 2369 of file aiks_unittests.cc.

2369  {
2370  Canvas canvas;
2371 
2372  canvas.DrawRect(Rect::MakeXYWH(100, 100, 300, 300), {.color = Color::Blue()});
2373 
2374  canvas.SaveLayer({
2375  .color = Color::Black().WithAlpha(0.5),
2376  .color_filter =
2377  ColorFilter::MakeBlend(BlendMode::kDestinationOver, Color::Red()),
2378  });
2379  canvas.DrawRect(Rect::MakeXYWH(100, 500, 300, 300), {.color = Color::Blue()});
2380  canvas.Restore();
2381 
2382  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2383 }

References impeller::Color::Black(), impeller::Color::Blue(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::kDestinationOver, impeller::ColorFilter::MakeBlend(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Color::Red(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Color::WithAlpha().

◆ TEST_P() [204/419]

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

Definition at line 2385 of file aiks_unittests.cc.

2385  {
2386  Canvas canvas;
2387 
2388  canvas.DrawRect(Rect::MakeXYWH(100, 100, 300, 300), {.color = Color::Blue()});
2389 
2390  canvas.SaveLayer({
2391  .color = Color::Black().WithAlpha(0.5),
2392  .image_filter = ImageFilter::MakeFromColorFilter(
2393  *ColorFilter::MakeBlend(BlendMode::kDestinationOver, Color::Red())),
2394  });
2395 
2396  canvas.DrawRect(Rect::MakeXYWH(100, 500, 300, 300), {.color = Color::Blue()});
2397  canvas.Restore();
2398 
2399  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2400 }

References impeller::Color::Black(), impeller::Color::Blue(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::kDestinationOver, impeller::ColorFilter::MakeBlend(), impeller::ImageFilter::MakeFromColorFilter(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Color::Red(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Color::WithAlpha().

◆ TEST_P() [205/419]

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

Definition at line 2402 of file aiks_unittests.cc.

2402  {
2403  Canvas canvas;
2404 
2405  canvas.DrawRect(Rect::MakeXYWH(100, 100, 300, 300), {.color = Color::Blue()});
2406 
2407  canvas.SaveLayer({
2408  .color = Color::Black().WithAlpha(0.5),
2409  .color_filter =
2410  ColorFilter::MakeBlend(BlendMode::kDestinationOver, Color::Red()),
2411  });
2412 
2413  canvas.DrawRect(Rect::MakeXYWH(100, 500, 300, 300), {.color = Color::Blue()});
2414  canvas.Restore();
2415 
2416  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2417 }

References impeller::Color::Black(), impeller::Color::Blue(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::kDestinationOver, impeller::ColorFilter::MakeBlend(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Color::Red(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Color::WithAlpha().

◆ TEST_P() [206/419]

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

Definition at line 2588 of file aiks_unittests.cc.

2589  {
2590  Canvas canvas;
2591 
2592  auto image = std::make_shared<Image>(CreateTextureForFixture("airplane.jpg"));
2593  canvas.DrawImage(image, {100, 100}, {});
2594 
2595  canvas.SaveLayer({
2596  .color = Color::Black().WithAlpha(0.5),
2597  .image_filter = ImageFilter::MakeFromColorFilter(
2598  *ColorFilter::MakeMatrix({.array =
2599  {
2600  1, 0, 0, 0, 0, //
2601  0, 1, 0, 0, 0, //
2602  0, 0.2, 1, 0, 0, //
2603  0, 0, 0, 0.5, 0 //
2604  }})),
2605  .color_filter =
2606  ColorFilter::MakeBlend(BlendMode::kModulate, Color::Green()),
2607  });
2608  canvas.DrawImage(image, {100, 500}, {});
2609  canvas.Restore();
2610 
2611  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2612 }

References impeller::Color::Black(), impeller::Canvas::DrawImage(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::kModulate, impeller::ColorFilter::MakeBlend(), impeller::ImageFilter::MakeFromColorFilter(), impeller::ColorFilter::MakeMatrix(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Color::WithAlpha().

◆ TEST_P() [207/419]

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

Definition at line 2543 of file aiks_unittests.cc.

2543  {
2544  Canvas canvas;
2545 
2546  auto image = std::make_shared<Image>(CreateTextureForFixture("airplane.jpg"));
2547  canvas.DrawImage(image, {100, 100}, {});
2548 
2549  canvas.SaveLayer({
2550  .color = Color::Black().WithAlpha(0.5),
2551  .color_filter = ColorFilter::MakeMatrix({.array =
2552  {
2553  1, 0, 0, 0, 0, //
2554  0, 1, 0, 0, 0, //
2555  0, 0, 1, 0, 0, //
2556  0, 0, 0, 2, 0 //
2557  }}),
2558  });
2559  canvas.DrawImage(image, {100, 500}, {});
2560  canvas.Restore();
2561 
2562  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2563 }

References impeller::Color::Black(), impeller::Canvas::DrawImage(), impeller::Canvas::EndRecordingAsPicture(), impeller::ColorFilter::MakeMatrix(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Color::WithAlpha().

◆ TEST_P() [208/419]

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

Definition at line 2565 of file aiks_unittests.cc.

2565  {
2566  Canvas canvas;
2567 
2568  auto image = std::make_shared<Image>(CreateTextureForFixture("airplane.jpg"));
2569  canvas.DrawImage(image, {100, 100}, {});
2570 
2571  canvas.SaveLayer({
2572  .color = Color::Black().WithAlpha(0.5),
2573  .image_filter = ImageFilter::MakeFromColorFilter(
2574  *ColorFilter::MakeMatrix({.array =
2575  {
2576  1, 0, 0, 0, 0, //
2577  0, 1, 0, 0, 0, //
2578  0, 0, 1, 0, 0, //
2579  0, 0, 0, 2, 0 //
2580  }})),
2581  });
2582  canvas.DrawImage(image, {100, 500}, {});
2583  canvas.Restore();
2584 
2585  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2586 }

References impeller::Color::Black(), impeller::Canvas::DrawImage(), impeller::Canvas::EndRecordingAsPicture(), impeller::ImageFilter::MakeFromColorFilter(), impeller::ColorFilter::MakeMatrix(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Color::WithAlpha().

◆ TEST_P() [209/419]

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

Definition at line 3116 of file aiks_unittests.cc.

3116  {
3117  Canvas canvas;
3118  Paint paint;
3119  auto texture = CreateTextureForFixture("table_mountain_nx.png");
3120 
3121  paint.color_source = ColorSource::MakeImage(texture, Entity::TileMode::kClamp,
3122  Entity::TileMode::kClamp, {}, {});
3123 
3124  auto vertices = {Point(0, 0), Point(texture->GetSize().width, 0),
3125  Point(0, texture->GetSize().height)};
3126  std::vector<uint16_t> indices = {0u, 1u, 2u};
3127  std::vector<Point> texture_coordinates = {};
3128  std::vector<Color> vertex_colors = {};
3129  auto geometry = std::make_shared<VerticesGeometry>(
3130  vertices, indices, texture_coordinates, vertex_colors,
3131  Rect::MakeLTRB(0, 0, 1, 1), VerticesGeometry::VertexMode::kTriangleStrip);
3132 
3133  canvas.DrawVertices(geometry, BlendMode::kSourceOver, paint);
3134  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3135 }

References impeller::Paint::color_source, impeller::Canvas::DrawVertices(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kClamp, impeller::kSourceOver, impeller::VerticesGeometry::kTriangleStrip, impeller::ColorSource::MakeImage(), and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST_P() [210/419]

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

Definition at line 3138 of file aiks_unittests.cc.

3138  {
3139  Canvas canvas;
3140  Paint paint;
3141  auto texture = CreateTextureForFixture("table_mountain_nx.png");
3142 
3143  paint.color_source = ColorSource::MakeImage(
3144  texture, Entity::TileMode::kClamp, Entity::TileMode::kClamp, {},
3145  Matrix::MakeTranslation({100.0, 100.0}));
3146 
3147  auto vertices = {Point(0, 0), Point(texture->GetSize().width, 0),
3148  Point(0, texture->GetSize().height)};
3149  std::vector<uint16_t> indices = {0u, 1u, 2u};
3150  std::vector<Point> texture_coordinates = {};
3151  std::vector<Color> vertex_colors = {};
3152  auto geometry = std::make_shared<VerticesGeometry>(
3153  vertices, indices, texture_coordinates, vertex_colors,
3154  Rect::MakeLTRB(0, 0, 1, 1), VerticesGeometry::VertexMode::kTriangleStrip);
3155 
3156  canvas.DrawVertices(geometry, BlendMode::kSourceOver, paint);
3157  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3158 }

References impeller::Paint::color_source, impeller::Canvas::DrawVertices(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kClamp, impeller::kSourceOver, impeller::VerticesGeometry::kTriangleStrip, impeller::ColorSource::MakeImage(), impeller::TRect< Scalar >::MakeLTRB(), and impeller::Matrix::MakeTranslation().

◆ TEST_P() [211/419]

impeller::testing::TEST_P ( BlitPassTest  ,
BlitAcrossDifferentPixelFormatsFails   
)

Definition at line 18 of file blit_pass_unittests.cc.

18  {
19  ScopedValidationDisable scope; // avoid noise in output.
20  auto context = GetContext();
21  auto cmd_buffer = context->CreateCommandBuffer();
22  auto blit_pass = cmd_buffer->CreateBlitPass();
23 
24  TextureDescriptor src_desc;
25  src_desc.format = PixelFormat::kA8UNormInt;
26  src_desc.size = {100, 100};
27  src_desc.storage_mode = StorageMode::kHostVisible;
28  auto src = context->GetResourceAllocator()->CreateTexture(src_desc);
29 
30  TextureDescriptor dst_format;
31  dst_format.format = PixelFormat::kR8G8B8A8UNormInt;
32  dst_format.size = {100, 100};
33  dst_format.storage_mode = StorageMode::kHostVisible;
34  auto dst = context->GetResourceAllocator()->CreateTexture(dst_format);
35 
36  EXPECT_FALSE(blit_pass->AddCopy(src, dst));
37 }

References impeller::TextureDescriptor::format, impeller::kA8UNormInt, impeller::kHostVisible, impeller::kR8G8B8A8UNormInt, impeller::TextureDescriptor::size, and impeller::TextureDescriptor::storage_mode.

◆ TEST_P() [212/419]

impeller::testing::TEST_P ( BlitPassTest  ,
BlitAcrossDifferentSampleCountsFails   
)

Definition at line 39 of file blit_pass_unittests.cc.

39  {
40  ScopedValidationDisable scope; // avoid noise in output.
41  auto context = GetContext();
42  auto cmd_buffer = context->CreateCommandBuffer();
43  auto blit_pass = cmd_buffer->CreateBlitPass();
44 
45  TextureDescriptor src_desc;
46  src_desc.format = PixelFormat::kR8G8B8A8UNormInt;
47  src_desc.sample_count = SampleCount::kCount4;
48  src_desc.size = {100, 100};
49  auto src = context->GetResourceAllocator()->CreateTexture(src_desc);
50 
51  TextureDescriptor dst_format;
52  dst_format.format = PixelFormat::kR8G8B8A8UNormInt;
53  dst_format.size = {100, 100};
54  auto dst = context->GetResourceAllocator()->CreateTexture(dst_format);
55 
56  EXPECT_FALSE(blit_pass->AddCopy(src, dst));
57 }

References impeller::TextureDescriptor::format, impeller::kCount4, impeller::kR8G8B8A8UNormInt, impeller::TextureDescriptor::sample_count, and impeller::TextureDescriptor::size.

◆ TEST_P() [213/419]

impeller::testing::TEST_P ( BlitPassTest  ,
BlitPassesForMatchingFormats   
)

Definition at line 59 of file blit_pass_unittests.cc.

59  {
60  ScopedValidationDisable scope; // avoid noise in output.
61  auto context = GetContext();
62  auto cmd_buffer = context->CreateCommandBuffer();
63  auto blit_pass = cmd_buffer->CreateBlitPass();
64 
65  TextureDescriptor src_desc;
66  src_desc.format = PixelFormat::kR8G8B8A8UNormInt;
67  src_desc.size = {100, 100};
68  auto src = context->GetResourceAllocator()->CreateTexture(src_desc);
69 
70  TextureDescriptor dst_format;
71  dst_format.format = PixelFormat::kR8G8B8A8UNormInt;
72  dst_format.size = {100, 100};
73  auto dst = context->GetResourceAllocator()->CreateTexture(dst_format);
74 
75  EXPECT_TRUE(blit_pass->AddCopy(src, dst));
76 }

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

◆ TEST_P() [214/419]

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

impeller::testing::TEST_P ( ComputeSubgroupTest  ,
LargePath   
)

Definition at line 173 of file compute_subgroup_unittests.cc.

173  {
174  // The path in here is large enough to highlight issues around exceeding
175  // subgroup size.
176  using SS = StrokeComputeShader;
177 
178  auto context = GetContext();
179  ASSERT_TRUE(context);
180  ASSERT_TRUE(context->GetCapabilities()->SupportsComputeSubgroups());
181  size_t vertex_count = 0;
182  Scalar stroke_width = 1.0;
183 
184  auto vertex_buffer = CreateHostVisibleDeviceBuffer<SS::VertexBuffer<2048>>(
185  context, "VertexBuffer");
186  auto vertex_buffer_count =
187  CreateHostVisibleDeviceBuffer<SS::VertexBufferCount>(context,
188  "VertexCount");
189 
190  auto complex_path =
191  PathBuilder{}
192  .MoveTo({359.934, 96.6335})
193  .CubicCurveTo({358.189, 96.7055}, {356.436, 96.7908},
194  {354.673, 96.8895})
195  .CubicCurveTo({354.571, 96.8953}, {354.469, 96.9016},
196  {354.367, 96.9075})
197  .CubicCurveTo({352.672, 97.0038}, {350.969, 97.113},
198  {349.259, 97.2355})
199  .CubicCurveTo({349.048, 97.2506}, {348.836, 97.2678},
200  {348.625, 97.2834})
201  .CubicCurveTo({347.019, 97.4014}, {345.407, 97.5299},
202  {343.789, 97.6722})
203  .CubicCurveTo({343.428, 97.704}, {343.065, 97.7402},
204  {342.703, 97.7734})
205  .CubicCurveTo({341.221, 97.9086}, {339.736, 98.0505},
206  {338.246, 98.207})
207  .CubicCurveTo({337.702, 98.2642}, {337.156, 98.3292},
208  {336.612, 98.3894})
209  .CubicCurveTo({335.284, 98.5356}, {333.956, 98.6837},
210  {332.623, 98.8476})
211  .CubicCurveTo({332.495, 98.8635}, {332.366, 98.8818},
212  {332.237, 98.8982})
213  .LineTo({332.237, 102.601})
214  .LineTo({321.778, 102.601})
215  .LineTo({321.778, 100.382})
216  .CubicCurveTo({321.572, 100.413}, {321.367, 100.442},
217  {321.161, 100.476})
218  .CubicCurveTo({319.22, 100.79}, {317.277, 101.123},
219  {315.332, 101.479})
220  .CubicCurveTo({315.322, 101.481}, {315.311, 101.482},
221  {315.301, 101.484})
222  .LineTo({310.017, 105.94})
223  .LineTo({309.779, 105.427})
224  .LineTo({314.403, 101.651})
225  .CubicCurveTo({314.391, 101.653}, {314.379, 101.656},
226  {314.368, 101.658})
227  .CubicCurveTo({312.528, 102.001}, {310.687, 102.366},
228  {308.846, 102.748})
229  .CubicCurveTo({307.85, 102.955}, {306.855, 103.182}, {305.859, 103.4})
230  .CubicCurveTo({305.048, 103.579}, {304.236, 103.75},
231  {303.425, 103.936})
232  .LineTo({299.105, 107.578})
233  .LineTo({298.867, 107.065})
234  .LineTo({302.394, 104.185})
235  .LineTo({302.412, 104.171})
236  .CubicCurveTo({301.388, 104.409}, {300.366, 104.67},
237  {299.344, 104.921})
238  .CubicCurveTo({298.618, 105.1}, {297.89, 105.269}, {297.165, 105.455})
239  .CubicCurveTo({295.262, 105.94}, {293.36, 106.445},
240  {291.462, 106.979})
241  .CubicCurveTo({291.132, 107.072}, {290.802, 107.163},
242  {290.471, 107.257})
243  .CubicCurveTo({289.463, 107.544}, {288.455, 107.839},
244  {287.449, 108.139})
245  .CubicCurveTo({286.476, 108.431}, {285.506, 108.73},
246  {284.536, 109.035})
247  .CubicCurveTo({283.674, 109.304}, {282.812, 109.579},
248  {281.952, 109.859})
249  .CubicCurveTo({281.177, 110.112}, {280.406, 110.377},
250  {279.633, 110.638})
251  .CubicCurveTo({278.458, 111.037}, {277.256, 111.449},
252  {276.803, 111.607})
253  .CubicCurveTo({276.76, 111.622}, {276.716, 111.637},
254  {276.672, 111.653})
255  .CubicCurveTo({275.017, 112.239}, {273.365, 112.836},
256  {271.721, 113.463})
257  .LineTo({271.717, 113.449})
258  .CubicCurveTo({271.496, 113.496}, {271.238, 113.559},
259  {270.963, 113.628})
260  .CubicCurveTo({270.893, 113.645}, {270.822, 113.663},
261  {270.748, 113.682})
262  .CubicCurveTo({270.468, 113.755}, {270.169, 113.834},
263  {269.839, 113.926})
264  .CubicCurveTo({269.789, 113.94}, {269.732, 113.957},
265  {269.681, 113.972})
266  .CubicCurveTo({269.391, 114.053}, {269.081, 114.143},
267  {268.756, 114.239})
268  .CubicCurveTo({268.628, 114.276}, {268.5, 114.314},
269  {268.367, 114.354})
270  .CubicCurveTo({268.172, 114.412}, {267.959, 114.478},
271  {267.752, 114.54})
272  .CubicCurveTo({263.349, 115.964}, {258.058, 117.695},
273  {253.564, 119.252})
274  .CubicCurveTo({253.556, 119.255}, {253.547, 119.258},
275  {253.538, 119.261})
276  .CubicCurveTo({251.844, 119.849}, {250.056, 120.474},
277  {248.189, 121.131})
278  .CubicCurveTo({248, 121.197}, {247.812, 121.264}, {247.621, 121.331})
279  .CubicCurveTo({247.079, 121.522}, {246.531, 121.715},
280  {245.975, 121.912})
281  .CubicCurveTo({245.554, 122.06}, {245.126, 122.212},
282  {244.698, 122.364})
283  .CubicCurveTo({244.071, 122.586}, {243.437, 122.811},
284  {242.794, 123.04})
285  .CubicCurveTo({242.189, 123.255}, {241.58, 123.472},
286  {240.961, 123.693})
287  .CubicCurveTo({240.659, 123.801}, {240.357, 123.909},
288  {240.052, 124.018})
289  .CubicCurveTo({239.12, 124.351}, {238.18, 124.687}, {237.22, 125.032})
290  .LineTo({237.164, 125.003})
291  .CubicCurveTo({236.709, 125.184}, {236.262, 125.358},
292  {235.81, 125.538})
293  .CubicCurveTo({235.413, 125.68}, {234.994, 125.832},
294  {234.592, 125.977})
295  .CubicCurveTo({234.592, 125.977}, {234.591, 125.977},
296  {234.59, 125.977})
297  .CubicCurveTo({222.206, 130.435}, {207.708, 135.753},
298  {192.381, 141.429})
299  .CubicCurveTo({162.77, 151.336}, {122.17, 156.894}, {84.1123, 160})
300  .LineTo({360, 160})
301  .LineTo({360, 119.256})
302  .LineTo({360, 106.332})
303  .LineTo({360, 96.6307})
304  .CubicCurveTo({359.978, 96.6317}, {359.956, 96.6326},
305  {359.934, 96.6335})
306  .Close()
307  .TakePath();
308 
309  auto callback = [&](RenderPass& pass) -> bool {
310  ::memset(vertex_buffer_count->OnGetContents(), 0,
311  sizeof(SS::VertexBufferCount));
312  ::memset(vertex_buffer->OnGetContents(), 0, sizeof(SS::VertexBuffer<2048>));
313 
314  ContentContext renderer(context, nullptr);
315  if (!renderer.IsValid()) {
316  return false;
317  }
318 
319  ComputeTessellator{}
320  .SetStrokeWidth(stroke_width)
321  .Tessellate(
322  complex_path, renderer.GetTransientsBuffer(), context,
323  DeviceBuffer::AsBufferView(vertex_buffer),
324  DeviceBuffer::AsBufferView(vertex_buffer_count),
325  [vertex_buffer_count, &vertex_count](CommandBuffer::Status status) {
326  vertex_count = reinterpret_cast<SS::VertexBufferCount*>(
327  vertex_buffer_count->OnGetContents())
328  ->count;
329  });
330 
331  using VS = SolidFillPipeline::VertexShader;
332 
333  pass.SetCommandLabel("Draw Stroke");
334  pass.SetStencilReference(0);
335 
336  ContentContextOptions options;
337  options.sample_count = pass.GetRenderTarget().GetSampleCount();
338  options.color_attachment_pixel_format =
339  pass.GetRenderTarget().GetRenderTargetPixelFormat();
340  options.has_depth_stencil_attachments =
341  pass.GetRenderTarget().GetStencilAttachment().has_value();
342  options.blend_mode = BlendMode::kSourceIn;
343  options.primitive_type = PrimitiveType::kTriangleStrip;
344 
345  options.stencil_mode =
346  ContentContextOptions::StencilMode::kLegacyClipIncrement;
347 
348  pass.SetPipeline(renderer.GetSolidFillPipeline(options));
349 
350  auto count = reinterpret_cast<SS::VertexBufferCount*>(
351  vertex_buffer_count->OnGetContents())
352  ->count;
353 
354  pass.SetVertexBuffer(
355  VertexBuffer{.vertex_buffer = DeviceBuffer::AsBufferView(vertex_buffer),
356  .vertex_count = count,
357  .index_type = IndexType::kNone});
358 
359  VS::FrameInfo frame_info;
360  auto world_matrix = Matrix::MakeScale(GetContentScale());
361  frame_info.mvp = pass.GetOrthographicTransform() * world_matrix;
362  frame_info.color = Color::Red().Premultiply();
363  VS::BindFrameInfo(
364  pass, renderer.GetTransientsBuffer().EmplaceUniform(frame_info));
365 
366  return pass.Draw().ok();
367  };
368  ASSERT_TRUE(OpenPlaygroundHere(callback));
369 }

References impeller::DeviceBuffer::AsBufferView(), impeller::ContentContextOptions::blend_mode, impeller::Close(), impeller::ContentContextOptions::color_attachment_pixel_format, impeller::HostBuffer::EmplaceUniform(), impeller::ContentContext::GetSolidFillPipeline(), impeller::ContentContext::GetTransientsBuffer(), impeller::ContentContextOptions::has_depth_stencil_attachments, impeller::ContentContext::IsValid(), impeller::ContentContextOptions::kLegacyClipIncrement, impeller::kNone, impeller::kSourceIn, impeller::kTriangleStrip, impeller::LineTo(), impeller::Matrix::MakeScale(), impeller::PathBuilder::MoveTo(), impeller::Color::Premultiply(), impeller::ContentContextOptions::primitive_type, impeller::Color::Red(), impeller::ContentContextOptions::sample_count, impeller::ComputeTessellator::SetStrokeWidth(), impeller::ContentContextOptions::stencil_mode, stroke_width, impeller::ComputeTessellator::Tessellate(), and impeller::VertexBuffer::vertex_buffer.

◆ TEST_P() [216/419]

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->OnGetContents(), 0,
74  sizeof(SS::VertexBufferCount));
75  ::memset(vertex_buffer->OnGetContents(), 0, sizeof(SS::VertexBuffer<2048>));
76  const auto* main_viewport = ImGui::GetMainViewport();
77  ImGui::SetNextWindowPos(
78  ImVec2(main_viewport->WorkPos.x + 650, main_viewport->WorkPos.y + 20));
79  ImGui::Begin("Path data", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
80  ImGui::InputTextMultiline("Path", svg_path_data,
81  IM_ARRAYSIZE(svg_path_data));
82  ImGui::DragFloat("Stroke width", &stroke_width, .1, 0.0, 25.0);
83 
84  SkPath sk_path;
85  if (SkParsePath::FromSVGString(svg_path_data, &sk_path)) {
86  std::promise<bool> promise;
87  auto future = promise.get_future();
88 
89  auto path = skia_conversions::ToPath(sk_path);
90  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
91  auto status =
92  ComputeTessellator{}
93  .SetStrokeWidth(stroke_width)
94  .Tessellate(path, *host_buffer, context,
95  DeviceBuffer::AsBufferView(vertex_buffer),
96  DeviceBuffer::AsBufferView(vertex_buffer_count),
97  [vertex_buffer_count, &vertex_count,
98  &promise](CommandBuffer::Status status) {
99  vertex_count =
100  reinterpret_cast<SS::VertexBufferCount*>(
101  vertex_buffer_count->OnGetContents())
102  ->count;
103  promise.set_value(
104  status == 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  pass.SetCommandLabel("Draw Stroke");
136  pass.SetStencilReference(0);
137 
138  ContentContextOptions options;
139  options.sample_count = pass.GetRenderTarget().GetSampleCount();
140  options.color_attachment_pixel_format =
141  pass.GetRenderTarget().GetRenderTargetPixelFormat();
142  options.has_depth_stencil_attachments =
143  pass.GetRenderTarget().GetStencilAttachment().has_value();
144  options.blend_mode = BlendMode::kSourceIn;
145  options.primitive_type = PrimitiveType::kTriangleStrip;
146 
147  options.stencil_mode =
148  ContentContextOptions::StencilMode::kLegacyClipIncrement;
149 
150  pass.SetPipeline(renderer.GetSolidFillPipeline(options));
151 
152  auto count = reinterpret_cast<SS::VertexBufferCount*>(
153  vertex_buffer_count->OnGetContents())
154  ->count;
155 
156  pass.SetVertexBuffer(
157  VertexBuffer{.vertex_buffer = DeviceBuffer::AsBufferView(vertex_buffer),
158  .vertex_count = count,
159  .index_type = IndexType::kNone});
160 
161  VS::FrameInfo frame_info;
162  auto world_matrix = Matrix::MakeScale(GetContentScale());
163  frame_info.mvp = pass.GetOrthographicTransform() * world_matrix;
164  frame_info.color = Color::Red().Premultiply();
165  VS::BindFrameInfo(
166  pass, renderer.GetTransientsBuffer().EmplaceUniform(frame_info));
167 
168  return pass.Draw().ok();
169  };
170  ASSERT_TRUE(OpenPlaygroundHere(callback));
171 }

References impeller::DeviceBuffer::AsBufferView(), impeller::ContentContextOptions::blend_mode, impeller::ContentContextOptions::color_attachment_pixel_format, impeller::HostBuffer::Create(), impeller::HostBuffer::EmplaceUniform(), impeller::ContentContext::GetSolidFillPipeline(), impeller::ContentContext::GetTransientsBuffer(), impeller::ContentContextOptions::has_depth_stencil_attachments, impeller::ContentContext::IsValid(), impeller::ComputeTessellator::kCommandInvalid, impeller::CommandBuffer::kCompleted, impeller::ContentContextOptions::kLegacyClipIncrement, impeller::kNone, impeller::ComputeTessellator::kOk, impeller::kSourceIn, impeller::ComputeTessellator::kTooManyComponents, impeller::kTriangleStrip, impeller::Matrix::MakeScale(), impeller::Color::Premultiply(), impeller::ContentContextOptions::primitive_type, impeller::Color::Red(), impeller::ContentContextOptions::sample_count, impeller::ComputeTessellator::SetStrokeWidth(), impeller::ContentContextOptions::stencil_mode, stroke_width, impeller::ComputeTessellator::Tessellate(), impeller::skia_conversions::ToPath(), and impeller::VertexBuffer::vertex_buffer.

◆ TEST_P() [217/419]

impeller::testing::TEST_P ( ComputeSubgroupTest  ,
QuadAndCubicInOnePath   
)

Definition at line 371 of file compute_subgroup_unittests.cc.

371  {
372  using SS = StrokeComputeShader;
373 
374  auto context = GetContext();
375  ASSERT_TRUE(context);
376  ASSERT_TRUE(context->GetCapabilities()->SupportsComputeSubgroups());
377 
378  auto vertex_buffer = CreateHostVisibleDeviceBuffer<SS::VertexBuffer<2048>>(
379  context, "VertexBuffer");
380  auto vertex_buffer_count =
381  CreateHostVisibleDeviceBuffer<SS::VertexBufferCount>(context,
382  "VertexBufferCount");
383 
384  auto path = PathBuilder{}
385  .AddCubicCurve({140, 20}, {73, 20}, {20, 74}, {20, 140})
386  .AddQuadraticCurve({20, 140}, {93, 90}, {100, 42})
387  .TakePath();
388 
389  auto tessellator = ComputeTessellator{};
390 
391  fml::AutoResetWaitableEvent latch;
392 
393  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
394  auto status = tessellator.Tessellate(
395  path, *host_buffer, context, DeviceBuffer::AsBufferView(vertex_buffer),
396  DeviceBuffer::AsBufferView(vertex_buffer_count),
397  [&latch](CommandBuffer::Status status) {
398  EXPECT_EQ(status, CommandBuffer::Status::kCompleted);
399  latch.Signal();
400  });
401 
402  ASSERT_EQ(status, ComputeTessellator::Status::kOk);
403 
404  auto callback = [&](RenderPass& pass) -> bool {
405  ContentContext renderer(context, nullptr);
406  if (!renderer.IsValid()) {
407  return false;
408  }
409 
410  using VS = SolidFillPipeline::VertexShader;
411 
412  pass.SetCommandLabel("Draw Stroke");
413  pass.SetStencilReference(0);
414 
415  ContentContextOptions options;
416  options.sample_count = pass.GetRenderTarget().GetSampleCount();
417  options.color_attachment_pixel_format =
418  pass.GetRenderTarget().GetRenderTargetPixelFormat();
419  options.has_depth_stencil_attachments =
420  pass.GetRenderTarget().GetStencilAttachment().has_value();
421  options.blend_mode = BlendMode::kSourceIn;
422  options.primitive_type = PrimitiveType::kTriangleStrip;
423 
424  options.stencil_mode =
425  ContentContextOptions::StencilMode::kLegacyClipIncrement;
426 
427  pass.SetPipeline(renderer.GetSolidFillPipeline(options));
428 
429  auto count = reinterpret_cast<SS::VertexBufferCount*>(
430  vertex_buffer_count->OnGetContents())
431  ->count;
432 
433  pass.SetVertexBuffer(
434  VertexBuffer{.vertex_buffer = DeviceBuffer::AsBufferView(vertex_buffer),
435  .vertex_count = count,
436  .index_type = IndexType::kNone});
437 
438  VS::FrameInfo frame_info;
439  auto world_matrix = Matrix::MakeScale(GetContentScale());
440  frame_info.mvp = pass.GetOrthographicTransform() * world_matrix;
441  frame_info.color = Color::Red().Premultiply();
442  VS::BindFrameInfo(
443  pass, renderer.GetTransientsBuffer().EmplaceUniform(frame_info));
444 
445  return pass.Draw().ok();
446  };
447  ASSERT_TRUE(OpenPlaygroundHere(callback));
448 
449  // The latch is down here because it's expected that on Metal the backend
450  // will take care of synchronizing the buffer between the compute and render
451  // pass usages, since it's not MTLHeap allocated. However, if playgrounds
452  // are disabled, no render pass actually gets submitted and we need to do a
453  // CPU latch here.
454  latch.Wait();
455 
456  auto vertex_count = reinterpret_cast<SS::VertexBufferCount*>(
457  vertex_buffer_count->OnGetContents())
458  ->count;
459  EXPECT_EQ(vertex_count, golden_cubic_and_quad_points.size());
460  auto vertex_buffer_data =
461  reinterpret_cast<SS::VertexBuffer<2048>*>(vertex_buffer->OnGetContents());
462  for (size_t i = 0; i < vertex_count; i++) {
463  EXPECT_LT(std::abs(golden_cubic_and_quad_points[i].x -
464  vertex_buffer_data->position[i].x),
465  1e-3);
466  EXPECT_LT(std::abs(golden_cubic_and_quad_points[i].y -
467  vertex_buffer_data->position[i].y),
468  1e-3);
469  }
470 }

References impeller::PathBuilder::AddCubicCurve(), impeller::DeviceBuffer::AsBufferView(), impeller::ContentContextOptions::blend_mode, impeller::ContentContextOptions::color_attachment_pixel_format, impeller::HostBuffer::Create(), impeller::HostBuffer::EmplaceUniform(), impeller::ContentContext::GetSolidFillPipeline(), impeller::ContentContext::GetTransientsBuffer(), golden_cubic_and_quad_points, impeller::ContentContextOptions::has_depth_stencil_attachments, impeller::ContentContext::IsValid(), impeller::CommandBuffer::kCompleted, impeller::ContentContextOptions::kLegacyClipIncrement, impeller::kNone, impeller::ComputeTessellator::kOk, impeller::kSourceIn, impeller::kTriangleStrip, impeller::Matrix::MakeScale(), impeller::Color::Premultiply(), impeller::ContentContextOptions::primitive_type, impeller::Color::Red(), impeller::ContentContextOptions::sample_count, impeller::ContentContextOptions::stencil_mode, and impeller::VertexBuffer::vertex_buffer.

◆ TEST_P() [218/419]

impeller::testing::TEST_P ( ComputeTest  ,
1DThreadgroupSizingIsCorrect   
)

Definition at line 175 of file compute_unittests.cc.

175  {
176  using CS = ThreadgroupSizingTestComputeShader;
177  auto context = GetContext();
178  ASSERT_TRUE(context);
179  ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
180 
181  using SamplePipelineBuilder = ComputePipelineBuilder<CS>;
182  auto pipeline_desc =
183  SamplePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
184  ASSERT_TRUE(pipeline_desc.has_value());
185  auto compute_pipeline =
186  context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
187  ASSERT_TRUE(compute_pipeline);
188 
189  auto cmd_buffer = context->CreateCommandBuffer();
190  auto pass = cmd_buffer->CreateComputePass();
191  ASSERT_TRUE(pass && pass->IsValid());
192 
193  static constexpr size_t kCount = 2048;
194 
195  pass->SetPipeline(compute_pipeline);
196 
197  auto output_buffer = CreateHostVisibleDeviceBuffer<CS::OutputData<kCount>>(
198  context, "Output Buffer");
199 
200  CS::BindOutputData(*pass, DeviceBuffer::AsBufferView(output_buffer));
201 
202  ASSERT_TRUE(pass->Compute(ISize(kCount, 1)).ok());
203  ASSERT_TRUE(pass->EncodeCommands());
204 
205  fml::AutoResetWaitableEvent latch;
206  ASSERT_TRUE(
207  context->GetCommandQueue()
208  ->Submit({cmd_buffer},
209  [&latch, output_buffer](CommandBuffer::Status status) {
210  EXPECT_EQ(status, CommandBuffer::Status::kCompleted);
211 
212  auto view = DeviceBuffer::AsBufferView(output_buffer);
213  EXPECT_EQ(view.range.length,
214  sizeof(CS::OutputData<kCount>));
215 
216  CS::OutputData<kCount>* output =
217  reinterpret_cast<CS::OutputData<kCount>*>(
218  output_buffer->OnGetContents());
219  EXPECT_TRUE(output);
220  EXPECT_EQ(output->data[kCount - 1], kCount - 1);
221  latch.Signal();
222  })
223  .ok());
224 
225  latch.Wait();
226 }

◆ TEST_P() [219/419]

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  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
377  ASSERT_TRUE(context);
378  ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
379 
380  using SamplePipelineBuilder = ComputePipelineBuilder<CS>;
381  auto pipeline_desc =
382  SamplePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
383  ASSERT_TRUE(pipeline_desc.has_value());
384  auto compute_pipeline =
385  context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
386  ASSERT_TRUE(compute_pipeline);
387 
388  auto cmd_buffer = context->CreateCommandBuffer();
389  auto pass = cmd_buffer->CreateComputePass();
390  ASSERT_TRUE(pass && pass->IsValid());
391 
392  static constexpr size_t kCount = 5;
393 
394  pass->SetPipeline(compute_pipeline);
395 
396  CS::Info info{.count = kCount};
397  CS::Input0<kCount> input_0;
398  CS::Input1<kCount> input_1;
399  for (size_t i = 0; i < kCount; i++) {
400  input_0.elements[i] = Vector4(2.0 + i, 3.0 + i, 4.0 + i, 5.0 * i);
401  input_1.elements[i] = Vector4(6.0, 7.0, 8.0, 9.0);
402  }
403 
404  input_0.fixed_array[1] = IPoint32(2, 2);
405  input_1.fixed_array[0] = UintPoint32(3, 3);
406  input_0.some_int = 5;
407  input_1.some_struct = CS::SomeStruct{.vf = Point(3, 4), .i = 42};
408 
409  auto output_buffer = CreateHostVisibleDeviceBuffer<CS::Output<kCount>>(
410  context, "Output Buffer");
411 
412  CS::BindInfo(*pass, host_buffer->EmplaceUniform(info));
413  CS::BindInput0(*pass, host_buffer->EmplaceStorageBuffer(input_0));
414  CS::BindInput1(*pass, host_buffer->EmplaceStorageBuffer(input_1));
415  CS::BindOutput(*pass, DeviceBuffer::AsBufferView(output_buffer));
416 
417  ASSERT_TRUE(pass->Compute(ISize(kCount, 1)).ok());
418  ASSERT_TRUE(pass->EncodeCommands());
419 
420  fml::AutoResetWaitableEvent latch;
421  ASSERT_TRUE(
422  context->GetCommandQueue()
423  ->Submit(
424  {cmd_buffer},
425  [&latch, output_buffer, &input_0,
426  &input_1](CommandBuffer::Status status) {
427  EXPECT_EQ(status, CommandBuffer::Status::kCompleted);
428 
429  auto view = DeviceBuffer::AsBufferView(output_buffer);
430  EXPECT_EQ(view.range.length, sizeof(CS::Output<kCount>));
431 
432  CS::Output<kCount>* output =
433  reinterpret_cast<CS::Output<kCount>*>(
434  output_buffer->OnGetContents());
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,
440  Vector4(computed.x + 2 + input_1.some_struct.i,
441  computed.y + 3 + input_1.some_struct.vf.x,
442  computed.z + 5 + input_1.some_struct.vf.y,
443  computed.w));
444  }
445  latch.Signal();
446  })
447  .ok());
448 
449  latch.Wait();
450 }

◆ TEST_P() [220/419]

impeller::testing::TEST_P ( ComputeTest  ,
CanComputePrefixSum   
)

Definition at line 109 of file compute_unittests.cc.

109  {
110  using CS = PrefixSumTestComputeShader;
111  auto context = GetContext();
112  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
113  ASSERT_TRUE(context);
114  ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
115 
116  using SamplePipelineBuilder = ComputePipelineBuilder<CS>;
117  auto pipeline_desc =
118  SamplePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
119  ASSERT_TRUE(pipeline_desc.has_value());
120  auto compute_pipeline =
121  context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
122  ASSERT_TRUE(compute_pipeline);
123 
124  auto cmd_buffer = context->CreateCommandBuffer();
125  auto pass = cmd_buffer->CreateComputePass();
126  ASSERT_TRUE(pass && pass->IsValid());
127 
128  static constexpr size_t kCount = 5;
129 
130  pass->SetPipeline(compute_pipeline);
131 
132  CS::InputData<kCount> input_data;
133  input_data.count = kCount;
134  for (size_t i = 0; i < kCount; i++) {
135  input_data.data[i] = 1 + i;
136  }
137 
138  auto output_buffer = CreateHostVisibleDeviceBuffer<CS::OutputData<kCount>>(
139  context, "Output Buffer");
140 
141  CS::BindInputData(*pass, host_buffer->EmplaceStorageBuffer(input_data));
142  CS::BindOutputData(*pass, DeviceBuffer::AsBufferView(output_buffer));
143 
144  ASSERT_TRUE(pass->Compute(ISize(kCount, 1)).ok());
145  ASSERT_TRUE(pass->EncodeCommands());
146 
147  fml::AutoResetWaitableEvent latch;
148  ASSERT_TRUE(
149  context->GetCommandQueue()
150  ->Submit({cmd_buffer},
151  [&latch, output_buffer](CommandBuffer::Status status) {
152  EXPECT_EQ(status, CommandBuffer::Status::kCompleted);
153 
154  auto view = DeviceBuffer::AsBufferView(output_buffer);
155  EXPECT_EQ(view.range.length,
156  sizeof(CS::OutputData<kCount>));
157 
158  CS::OutputData<kCount>* output =
159  reinterpret_cast<CS::OutputData<kCount>*>(
160  output_buffer->OnGetContents());
161  EXPECT_TRUE(output);
162 
163  constexpr uint32_t expected[kCount] = {1, 3, 6, 10, 15};
164  for (size_t i = 0; i < kCount; i++) {
165  auto computed_sum = output->data[i];
166  EXPECT_EQ(computed_sum, expected[i]);
167  }
168  latch.Signal();
169  })
170  .ok());
171 
172  latch.Wait();
173 }

References impeller::DeviceBuffer::AsBufferView(), and impeller::HostBuffer::Create().

◆ TEST_P() [221/419]

impeller::testing::TEST_P ( ComputeTest  ,
CanComputePrefixSumLargeInteractive   
)

Definition at line 228 of file compute_unittests.cc.

228  {
229  using CS = PrefixSumTestComputeShader;
230 
231  auto context = GetContext();
232  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
233 
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->SetPipeline(compute_pipeline);
250 
251  CS::InputData<kCount> input_data;
252  input_data.count = kCount;
253  for (size_t i = 0; i < kCount; i++) {
254  input_data.data[i] = 1 + i;
255  }
256 
257  auto output_buffer = CreateHostVisibleDeviceBuffer<CS::OutputData<kCount>>(
258  context, "Output Buffer");
259 
260  CS::BindInputData(*pass, host_buffer->EmplaceStorageBuffer(input_data));
261  CS::BindOutputData(*pass, DeviceBuffer::AsBufferView(output_buffer));
262 
263  pass->Compute(ISize(kCount, 1));
264  pass->EncodeCommands();
265  host_buffer->Reset();
266  return context->GetCommandQueue()->Submit({cmd_buffer}).ok();
267  };
268  ASSERT_TRUE(OpenPlaygroundHere(callback));
269 }

◆ TEST_P() [222/419]

impeller::testing::TEST_P ( ComputeTest  ,
CanCreateComputePass   
)

Definition at line 30 of file compute_unittests.cc.

30  {
31  using CS = SampleComputeShader;
32  auto context = GetContext();
33  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
34  ASSERT_TRUE(context);
35  ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
36 
37  using SamplePipelineBuilder = ComputePipelineBuilder<CS>;
38  auto pipeline_desc =
39  SamplePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
40  ASSERT_TRUE(pipeline_desc.has_value());
41  auto compute_pipeline =
42  context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
43  ASSERT_TRUE(compute_pipeline);
44 
45  auto cmd_buffer = context->CreateCommandBuffer();
46  auto pass = cmd_buffer->CreateComputePass();
47  ASSERT_TRUE(pass && pass->IsValid());
48 
49  static constexpr size_t kCount = 5;
50 
51  pass->SetPipeline(compute_pipeline);
52 
53  CS::Info info{.count = kCount};
54  CS::Input0<kCount> input_0;
55  CS::Input1<kCount> input_1;
56  for (size_t i = 0; i < kCount; i++) {
57  input_0.elements[i] = Vector4(2.0 + i, 3.0 + i, 4.0 + i, 5.0 * i);
58  input_1.elements[i] = Vector4(6.0, 7.0, 8.0, 9.0);
59  }
60 
61  input_0.fixed_array[1] = IPoint32(2, 2);
62  input_1.fixed_array[0] = UintPoint32(3, 3);
63  input_0.some_int = 5;
64  input_1.some_struct = CS::SomeStruct{.vf = Point(3, 4), .i = 42};
65 
66  auto output_buffer = CreateHostVisibleDeviceBuffer<CS::Output<kCount>>(
67  context, "Output Buffer");
68 
69  CS::BindInfo(*pass, host_buffer->EmplaceUniform(info));
70  CS::BindInput0(*pass, host_buffer->EmplaceStorageBuffer(input_0));
71  CS::BindInput1(*pass, host_buffer->EmplaceStorageBuffer(input_1));
72  CS::BindOutput(*pass, DeviceBuffer::AsBufferView(output_buffer));
73 
74  ASSERT_TRUE(pass->Compute(ISize(kCount, 1)).ok());
75  ASSERT_TRUE(pass->EncodeCommands());
76 
77  fml::AutoResetWaitableEvent latch;
78  ASSERT_TRUE(
79  context->GetCommandQueue()
80  ->Submit(
81  {cmd_buffer},
82  [&latch, output_buffer, &input_0,
83  &input_1](CommandBuffer::Status status) {
84  EXPECT_EQ(status, CommandBuffer::Status::kCompleted);
85 
86  auto view = DeviceBuffer::AsBufferView(output_buffer);
87  EXPECT_EQ(view.range.length, sizeof(CS::Output<kCount>));
88 
89  CS::Output<kCount>* output =
90  reinterpret_cast<CS::Output<kCount>*>(
91  output_buffer->OnGetContents());
92  EXPECT_TRUE(output);
93  for (size_t i = 0; i < kCount; i++) {
94  Vector4 vector = output->elements[i];
95  Vector4 computed = input_0.elements[i] * input_1.elements[i];
96  EXPECT_EQ(vector,
97  Vector4(computed.x + 2 + input_1.some_struct.i,
98  computed.y + 3 + input_1.some_struct.vf.x,
99  computed.z + 5 + input_1.some_struct.vf.y,
100  computed.w));
101  }
102  latch.Signal();
103  })
104  .ok());
105 
106  latch.Wait();
107 }

References impeller::DeviceBuffer::AsBufferView(), and impeller::HostBuffer::Create().

◆ TEST_P() [223/419]

impeller::testing::TEST_P ( ComputeTest  ,
CapabilitiesReportSupport   
)

Definition at line 24 of file compute_unittests.cc.

24  {
25  auto context = GetContext();
26  ASSERT_TRUE(context);
27  ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
28 }

◆ TEST_P() [224/419]

impeller::testing::TEST_P ( ComputeTest  ,
MultiStageInputAndOutput   
)

Definition at line 271 of file compute_unittests.cc.

271  {
272  using CS1 = Stage1ComputeShader;
273  using Stage1PipelineBuilder = ComputePipelineBuilder<CS1>;
274  using CS2 = Stage2ComputeShader;
275  using Stage2PipelineBuilder = ComputePipelineBuilder<CS2>;
276 
277  auto context = GetContext();
278  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
279  ASSERT_TRUE(context);
280  ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
281 
282  auto pipeline_desc_1 =
283  Stage1PipelineBuilder::MakeDefaultPipelineDescriptor(*context);
284  ASSERT_TRUE(pipeline_desc_1.has_value());
285  auto compute_pipeline_1 =
286  context->GetPipelineLibrary()->GetPipeline(pipeline_desc_1).Get();
287  ASSERT_TRUE(compute_pipeline_1);
288 
289  auto pipeline_desc_2 =
290  Stage2PipelineBuilder::MakeDefaultPipelineDescriptor(*context);
291  ASSERT_TRUE(pipeline_desc_2.has_value());
292  auto compute_pipeline_2 =
293  context->GetPipelineLibrary()->GetPipeline(pipeline_desc_2).Get();
294  ASSERT_TRUE(compute_pipeline_2);
295 
296  auto cmd_buffer = context->CreateCommandBuffer();
297  auto pass = cmd_buffer->CreateComputePass();
298  ASSERT_TRUE(pass && pass->IsValid());
299 
300  static constexpr size_t kCount1 = 5;
301  static constexpr size_t kCount2 = kCount1 * 2;
302 
303  CS1::Input<kCount1> input_1;
304  input_1.count = kCount1;
305  for (size_t i = 0; i < kCount1; i++) {
306  input_1.elements[i] = i;
307  }
308 
309  CS2::Input<kCount2> input_2;
310  input_2.count = kCount2;
311  for (size_t i = 0; i < kCount2; i++) {
312  input_2.elements[i] = i;
313  }
314 
315  auto output_buffer_1 = CreateHostVisibleDeviceBuffer<CS1::Output<kCount2>>(
316  context, "Output Buffer Stage 1");
317  auto output_buffer_2 = CreateHostVisibleDeviceBuffer<CS2::Output<kCount2>>(
318  context, "Output Buffer Stage 2");
319 
320  {
321  pass->SetPipeline(compute_pipeline_1);
322 
323  CS1::BindInput(*pass, host_buffer->EmplaceStorageBuffer(input_1));
324  CS1::BindOutput(*pass, DeviceBuffer::AsBufferView(output_buffer_1));
325 
326  ASSERT_TRUE(pass->Compute(ISize(512, 1)).ok());
327  pass->AddBufferMemoryBarrier();
328  }
329 
330  {
331  pass->SetPipeline(compute_pipeline_2);
332 
333  CS1::BindInput(*pass, DeviceBuffer::AsBufferView(output_buffer_1));
334  CS2::BindOutput(*pass, DeviceBuffer::AsBufferView(output_buffer_2));
335  ASSERT_TRUE(pass->Compute(ISize(512, 1)).ok());
336  }
337 
338  ASSERT_TRUE(pass->EncodeCommands());
339 
340  fml::AutoResetWaitableEvent latch;
341  ASSERT_TRUE(
342  context->GetCommandQueue()
343  ->Submit({cmd_buffer},
344  [&latch, &output_buffer_1,
345  &output_buffer_2](CommandBuffer::Status status) {
346  EXPECT_EQ(status, CommandBuffer::Status::kCompleted);
347 
348  CS1::Output<kCount2>* output_1 =
349  reinterpret_cast<CS1::Output<kCount2>*>(
350  output_buffer_1->OnGetContents());
351  EXPECT_TRUE(output_1);
352  EXPECT_EQ(output_1->count, 10u);
353  EXPECT_THAT(
354  output_1->elements,
355  ::testing::ElementsAre(0, 0, 2, 3, 4, 6, 6, 9, 8, 12));
356 
357  CS2::Output<kCount2>* output_2 =
358  reinterpret_cast<CS2::Output<kCount2>*>(
359  output_buffer_2->OnGetContents());
360  EXPECT_TRUE(output_2);
361  EXPECT_EQ(output_2->count, 10u);
362  EXPECT_THAT(output_2->elements,
363  ::testing::ElementsAre(0, 0, 4, 6, 8, 12, 12,
364  18, 16, 24));
365 
366  latch.Signal();
367  })
368  .ok());
369 
370  latch.Wait();
371 }

References impeller::kCount1.

◆ TEST_P() [225/419]

impeller::testing::TEST_P ( ComputeTest  ,
ReturnsEarlyWhenAnyGridDimensionIsZero   
)

Definition at line 452 of file compute_unittests.cc.

452  {
453  using CS = SampleComputeShader;
454  auto context = GetContext();
455  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
456  ASSERT_TRUE(context);
457  ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
458 
459  using SamplePipelineBuilder = ComputePipelineBuilder<CS>;
460  auto pipeline_desc =
461  SamplePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
462  ASSERT_TRUE(pipeline_desc.has_value());
463  auto compute_pipeline =
464  context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
465  ASSERT_TRUE(compute_pipeline);
466 
467  auto cmd_buffer = context->CreateCommandBuffer();
468  auto pass = cmd_buffer->CreateComputePass();
469  ASSERT_TRUE(pass && pass->IsValid());
470 
471  static constexpr size_t kCount = 5;
472 
473  pass->SetPipeline(compute_pipeline);
474 
475  CS::Info info{.count = kCount};
476  CS::Input0<kCount> input_0;
477  CS::Input1<kCount> input_1;
478  for (size_t i = 0; i < kCount; i++) {
479  input_0.elements[i] = Vector4(2.0 + i, 3.0 + i, 4.0 + i, 5.0 * i);
480  input_1.elements[i] = Vector4(6.0, 7.0, 8.0, 9.0);
481  }
482 
483  input_0.fixed_array[1] = IPoint32(2, 2);
484  input_1.fixed_array[0] = UintPoint32(3, 3);
485  input_0.some_int = 5;
486  input_1.some_struct = CS::SomeStruct{.vf = Point(3, 4), .i = 42};
487 
488  auto output_buffer = CreateHostVisibleDeviceBuffer<CS::Output<kCount>>(
489  context, "Output Buffer");
490 
491  CS::BindInfo(*pass, host_buffer->EmplaceUniform(info));
492  CS::BindInput0(*pass, host_buffer->EmplaceStorageBuffer(input_0));
493  CS::BindInput1(*pass, host_buffer->EmplaceStorageBuffer(input_1));
494  CS::BindOutput(*pass, DeviceBuffer::AsBufferView(output_buffer));
495 
496  // Intentionally making the grid size zero in one dimension. No GPU will
497  // tolerate this.
498  EXPECT_FALSE(pass->Compute(ISize(0, 1)).ok());
499  pass->EncodeCommands();
500 }

◆ TEST_P() [226/419]

impeller::testing::TEST_P ( DisplayListTest  ,
CanBlendDstOverAndDstCorrectly   
)

Definition at line 1266 of file dl_unittests.cc.

1266  {
1267  flutter::DisplayListBuilder builder;
1268 
1269  {
1270  builder.SaveLayer(nullptr, nullptr);
1271  builder.Translate(100, 100);
1272  flutter::DlPaint paint;
1273  paint.setColor(flutter::DlColor::kRed());
1274  builder.DrawRect(SkRect::MakeSize({200, 200}), paint);
1275  paint.setColor(flutter::DlColor::kBlue().withAlpha(127));
1276  paint.setBlendMode(flutter::DlBlendMode::kSrcOver);
1277  builder.DrawRect(SkRect::MakeSize({200, 200}), paint);
1278  builder.Restore();
1279  }
1280  {
1281  builder.SaveLayer(nullptr, nullptr);
1282  builder.Translate(300, 100);
1283  flutter::DlPaint paint;
1284  paint.setColor(flutter::DlColor::kBlue().withAlpha(127));
1285  builder.DrawRect(SkRect::MakeSize({200, 200}), paint);
1286  paint.setColor(flutter::DlColor::kRed());
1287  paint.setBlendMode(flutter::DlBlendMode::kDstOver);
1288  builder.DrawRect(SkRect::MakeSize({200, 200}), paint);
1289  builder.Restore();
1290  }
1291  {
1292  builder.SaveLayer(nullptr, nullptr);
1293  builder.Translate(100, 300);
1294  flutter::DlPaint paint;
1295  paint.setColor(flutter::DlColor::kRed());
1296  builder.DrawRect(SkRect::MakeSize({200, 200}), paint);
1297  paint.setColor(flutter::DlColor::kBlue().withAlpha(127));
1298  paint.setBlendMode(flutter::DlBlendMode::kSrc);
1299  builder.DrawRect(SkRect::MakeSize({200, 200}), paint);
1300  builder.Restore();
1301  }
1302  {
1303  builder.SaveLayer(nullptr, nullptr);
1304  builder.Translate(300, 300);
1305  flutter::DlPaint paint;
1306  paint.setColor(flutter::DlColor::kBlue().withAlpha(127));
1307  builder.DrawRect(SkRect::MakeSize({200, 200}), paint);
1308  paint.setColor(flutter::DlColor::kRed());
1309  paint.setBlendMode(flutter::DlBlendMode::kDst);
1310  builder.DrawRect(SkRect::MakeSize({200, 200}), paint);
1311  builder.Restore();
1312  }
1313 
1314  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1315 }

◆ TEST_P() [227/419]

impeller::testing::TEST_P ( DisplayListTest  ,
CanClampTheResultingColorOfColorMatrixFilter   
)

Definition at line 616 of file dl_unittests.cc.

616  {
617  auto texture = CreateTextureForFixture("boston.jpg");
618  const float inner_color_matrix[20] = {
619  1, 0, 0, 0, 0, //
620  0, 1, 0, 0, 0, //
621  0, 0, 1, 0, 0, //
622  0, 0, 0, 2, 0, //
623  };
624  const float outer_color_matrix[20] = {
625  1, 0, 0, 0, 0, //
626  0, 1, 0, 0, 0, //
627  0, 0, 1, 0, 0, //
628  0, 0, 0, 0.5, 0, //
629  };
630  auto inner_color_filter =
631  std::make_shared<flutter::DlMatrixColorFilter>(inner_color_matrix);
632  auto outer_color_filter =
633  std::make_shared<flutter::DlMatrixColorFilter>(outer_color_matrix);
634  auto inner =
635  std::make_shared<flutter::DlColorFilterImageFilter>(inner_color_filter);
636  auto outer =
637  std::make_shared<flutter::DlColorFilterImageFilter>(outer_color_filter);
638  auto compose = std::make_shared<flutter::DlComposeImageFilter>(outer, inner);
639 
640  flutter::DisplayListBuilder builder;
641  flutter::DlPaint paint;
642  paint.setImageFilter(compose.get());
643  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
644  flutter::DlImageSampling::kNearestNeighbor, &paint);
645  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
646 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [228/419]

impeller::testing::TEST_P ( DisplayListTest  ,
CanConvertTriangleFanToTriangles   
)

Definition at line 977 of file dl_unittests.cc.

977  {
978  constexpr Scalar hexagon_radius = 125;
979  auto hex_start = Point(200.0, -hexagon_radius + 200.0);
980  auto center_to_flat = 1.73 / 2 * hexagon_radius;
981 
982  // clang-format off
983  std::vector<SkPoint> vertices = {
984  SkPoint::Make(hex_start.x, hex_start.y),
985  SkPoint::Make(hex_start.x + center_to_flat, hex_start.y + 0.5 * hexagon_radius),
986  SkPoint::Make(hex_start.x + center_to_flat, hex_start.y + 1.5 * hexagon_radius),
987  SkPoint::Make(hex_start.x + center_to_flat, hex_start.y + 1.5 * hexagon_radius),
988  SkPoint::Make(hex_start.x, hex_start.y + 2 * hexagon_radius),
989  SkPoint::Make(hex_start.x, hex_start.y + 2 * hexagon_radius),
990  SkPoint::Make(hex_start.x - center_to_flat, hex_start.y + 1.5 * hexagon_radius),
991  SkPoint::Make(hex_start.x - center_to_flat, hex_start.y + 1.5 * hexagon_radius),
992  SkPoint::Make(hex_start.x - center_to_flat, hex_start.y + 0.5 * hexagon_radius)
993  };
994  // clang-format on
995  auto paint = flutter::DlPaint(flutter::DlColor::kDarkGrey());
996  auto dl_vertices = flutter::DlVertices::Make(
997  flutter::DlVertexMode::kTriangleFan, vertices.size(), vertices.data(),
998  nullptr, nullptr);
999  flutter::DisplayListBuilder builder;
1000  builder.DrawVertices(dl_vertices, flutter::DlBlendMode::kSrcOver, paint);
1001  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1002 }

◆ TEST_P() [229/419]

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

Definition at line 406 of file dl_unittests.cc.

406  {
407  flutter::DisplayListBuilder builder;
408  flutter::DlPaint paint;
409 
410  paint.setColor(flutter::DlColor::kRed());
411  paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
412  paint.setStrokeWidth(10);
413 
414  builder.Translate(300, 300);
415 
416  // Move to (50, 50) and draw lines from:
417  // 1. (50, height)
418  // 2. (width, height)
419  // 3. (width, 50)
420  SkPath path;
421  path.moveTo(50, 50);
422  path.lineTo(50, 100);
423  path.lineTo(100, 100);
424  path.lineTo(100, 50);
425  builder.DrawPath(path, paint);
426 
427  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
428 }

◆ TEST_P() [230/419]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawArc   
)

Definition at line 152 of file dl_unittests.cc.

152  {
153  auto callback = [&]() {
154  static float start_angle = 45;
155  static float sweep_angle = 270;
156  static float stroke_width = 10;
157  static bool use_center = true;
158 
159  static int selected_cap = 0;
160  const char* cap_names[] = {"Butt", "Round", "Square"};
161  flutter::DlStrokeCap cap;
162 
163  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
164  ImGui::SliderFloat("Start angle", &start_angle, -360, 360);
165  ImGui::SliderFloat("Sweep angle", &sweep_angle, -360, 360);
166  ImGui::SliderFloat("Stroke width", &stroke_width, 0, 300);
167  ImGui::Combo("Cap", &selected_cap, cap_names,
168  sizeof(cap_names) / sizeof(char*));
169  ImGui::Checkbox("Use center", &use_center);
170  ImGui::End();
171 
172  switch (selected_cap) {
173  case 0:
174  cap = flutter::DlStrokeCap::kButt;
175  break;
176  case 1:
177  cap = flutter::DlStrokeCap::kRound;
178  break;
179  case 2:
180  cap = flutter::DlStrokeCap::kSquare;
181  break;
182  default:
183  cap = flutter::DlStrokeCap::kButt;
184  break;
185  }
186 
187  static PlaygroundPoint point_a(Point(200, 200), 20, Color::White());
188  static PlaygroundPoint point_b(Point(400, 400), 20, Color::White());
189  auto [p1, p2] = DrawPlaygroundLine(point_a, point_b);
190 
191  flutter::DisplayListBuilder builder;
192  flutter::DlPaint paint;
193 
194  Vector2 scale = GetContentScale();
195  builder.Scale(scale.x, scale.y);
196  paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
197  paint.setStrokeCap(cap);
198  paint.setStrokeJoin(flutter::DlStrokeJoin::kMiter);
199  paint.setStrokeMiter(10);
200  auto rect = SkRect::MakeLTRB(p1.x, p1.y, p2.x, p2.y);
201  paint.setColor(flutter::DlColor::kGreen());
202  paint.setStrokeWidth(2);
203  builder.DrawRect(rect, paint);
204  paint.setColor(flutter::DlColor::kRed());
205  paint.setStrokeWidth(stroke_width);
206  builder.DrawArc(rect, start_angle, sweep_angle, use_center, paint);
207 
208  return builder.Build();
209  };
210  ASSERT_TRUE(OpenPlaygroundHere(callback));
211 }

References impeller::DrawPlaygroundLine(), scale, stroke_width, and impeller::Color::White().

◆ TEST_P() [231/419]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawBackdropFilter   
)

Definition at line 648 of file dl_unittests.cc.

648  {
649  auto texture = CreateTextureForFixture("embarcadero.jpg");
650 
651  auto callback = [&]() {
652  static float sigma[] = {10, 10};
653  static float ctm_scale = 1;
654  static bool use_bounds = true;
655  static bool draw_circle = true;
656  static bool add_clip = true;
657 
658  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
659  ImGui::SliderFloat2("Sigma", sigma, 0, 100);
660  ImGui::SliderFloat("Scale", &ctm_scale, 0, 10);
661  ImGui::NewLine();
662  ImGui::TextWrapped(
663  "If everything is working correctly, none of the options below should "
664  "impact the filter's appearance.");
665  ImGui::Checkbox("Use SaveLayer bounds", &use_bounds);
666  ImGui::Checkbox("Draw child element", &draw_circle);
667  ImGui::Checkbox("Add pre-clip", &add_clip);
668  ImGui::End();
669 
670  flutter::DisplayListBuilder builder;
671 
672  Vector2 scale = ctm_scale * GetContentScale();
673  builder.Scale(scale.x, scale.y);
674 
675  auto filter = flutter::DlBlurImageFilter(sigma[0], sigma[1],
676  flutter::DlTileMode::kClamp);
677 
678  std::optional<SkRect> bounds;
679  if (use_bounds) {
680  static PlaygroundPoint point_a(Point(350, 150), 20, Color::White());
681  static PlaygroundPoint point_b(Point(800, 600), 20, Color::White());
682  auto [p1, p2] = DrawPlaygroundLine(point_a, point_b);
683  bounds = SkRect::MakeLTRB(p1.x, p1.y, p2.x, p2.y);
684  }
685 
686  // Insert a clip to test that the backdrop filter handles stencil depths > 0
687  // correctly.
688  if (add_clip) {
689  builder.ClipRect(SkRect::MakeLTRB(0, 0, 99999, 99999),
690  flutter::DlCanvas::ClipOp::kIntersect, true);
691  }
692 
693  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(200, 200),
694  flutter::DlImageSampling::kNearestNeighbor, nullptr);
695  builder.SaveLayer(bounds.has_value() ? &bounds.value() : nullptr, nullptr,
696  &filter);
697 
698  if (draw_circle) {
699  static PlaygroundPoint center_point(Point(500, 400), 20, Color::Red());
700  auto circle_center = DrawPlaygroundPoint(center_point);
701 
702  flutter::DlPaint paint;
703  paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
704  paint.setStrokeCap(flutter::DlStrokeCap::kButt);
705  paint.setStrokeJoin(flutter::DlStrokeJoin::kBevel);
706  paint.setStrokeWidth(10);
707  paint.setColor(flutter::DlColor::kRed().withAlpha(100));
708  builder.DrawCircle({circle_center.x, circle_center.y}, 100, paint);
709  }
710 
711  return builder.Build();
712  };
713 
714  ASSERT_TRUE(OpenPlaygroundHere(callback));
715 }

References impeller::DrawPlaygroundLine(), impeller::DrawPlaygroundPoint(), impeller::DlImageImpeller::Make(), impeller::Color::Red(), scale, and impeller::Color::White().

◆ TEST_P() [232/419]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawCapsAndJoins   
)

Definition at line 106 of file dl_unittests.cc.

106  {
107  flutter::DisplayListBuilder builder;
108  flutter::DlPaint paint;
109 
110  paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
111  paint.setStrokeWidth(30);
112  paint.setColor(flutter::DlColor::kRed());
113 
114  auto path =
115  SkPathBuilder{}.moveTo(-50, 0).lineTo(0, -50).lineTo(50, 0).snapshot();
116 
117  builder.Translate(100, 100);
118  {
119  paint.setStrokeCap(flutter::DlStrokeCap::kButt);
120  paint.setStrokeJoin(flutter::DlStrokeJoin::kMiter);
121  paint.setStrokeMiter(4);
122  builder.DrawPath(path, paint);
123  }
124 
125  {
126  builder.Save();
127  builder.Translate(0, 100);
128  // The joint in the path is 45 degrees. A miter length of 1 convert to a
129  // bevel in this case.
130  paint.setStrokeMiter(1);
131  builder.DrawPath(path, paint);
132  builder.Restore();
133  }
134 
135  builder.Translate(150, 0);
136  {
137  paint.setStrokeCap(flutter::DlStrokeCap::kSquare);
138  paint.setStrokeJoin(flutter::DlStrokeJoin::kBevel);
139  builder.DrawPath(path, paint);
140  }
141 
142  builder.Translate(150, 0);
143  {
144  paint.setStrokeCap(flutter::DlStrokeCap::kRound);
145  paint.setStrokeJoin(flutter::DlStrokeJoin::kRound);
146  builder.DrawPath(path, paint);
147  }
148 
149  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
150 }

◆ TEST_P() [233/419]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawCorrectlyWithColorFilterAndImageFilter   
)

Definition at line 1317 of file dl_unittests.cc.

1317  {
1318  flutter::DisplayListBuilder builder;
1319  const float green_color_matrix[20] = {
1320  0, 0, 0, 0, 0, //
1321  0, 0, 0, 0, 1, //
1322  0, 0, 0, 0, 0, //
1323  0, 0, 0, 1, 0, //
1324  };
1325  const float blue_color_matrix[20] = {
1326  0, 0, 0, 0, 0, //
1327  0, 0, 0, 0, 0, //
1328  0, 0, 0, 0, 1, //
1329  0, 0, 0, 1, 0, //
1330  };
1331  auto green_color_filter =
1332  std::make_shared<flutter::DlMatrixColorFilter>(green_color_matrix);
1333  auto blue_color_filter =
1334  std::make_shared<flutter::DlMatrixColorFilter>(blue_color_matrix);
1335  auto blue_image_filter =
1336  std::make_shared<flutter::DlColorFilterImageFilter>(blue_color_filter);
1337 
1338  flutter::DlPaint paint;
1339  paint.setColor(flutter::DlColor::kRed());
1340  paint.setColorFilter(green_color_filter);
1341  paint.setImageFilter(blue_image_filter);
1342  builder.DrawRect(SkRect::MakeLTRB(100, 100, 500, 500), paint);
1343  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1344 }

◆ TEST_P() [234/419]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawImage   
)

Definition at line 98 of file dl_unittests.cc.

98  {
99  auto texture = CreateTextureForFixture("embarcadero.jpg");
100  flutter::DisplayListBuilder builder;
101  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
102  flutter::DlImageSampling::kNearestNeighbor, nullptr);
103  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
104 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [235/419]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawNinePatchImage   
)

Definition at line 717 of file dl_unittests.cc.

717  {
718  // Image is drawn with corners to scale and center pieces stretched to fit.
719  auto texture = CreateTextureForFixture("embarcadero.jpg");
720  flutter::DisplayListBuilder builder;
721  auto size = texture->GetSize();
722  builder.DrawImageNine(
723  DlImageImpeller::Make(texture),
724  SkIRect::MakeLTRB(size.width / 4, size.height / 4, size.width * 3 / 4,
725  size.height * 3 / 4),
726  SkRect::MakeLTRB(0, 0, size.width * 2, size.height * 2),
727  flutter::DlFilterMode::kNearest, nullptr);
728  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
729 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [236/419]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawNinePatchImageCenterBiggerThanDest   
)

Definition at line 763 of file dl_unittests.cc.

763  {
764  // Edge case, the width and height of the corners does not leave any
765  // room for the center slices. Only the corners are displayed.
766  auto texture = CreateTextureForFixture("embarcadero.jpg");
767  flutter::DisplayListBuilder builder;
768  auto size = texture->GetSize();
769  builder.DrawImageNine(
770  DlImageImpeller::Make(texture),
771  SkIRect::MakeLTRB(size.width / 4, size.height / 4, size.width * 3 / 4,
772  size.height * 3 / 4),
773  SkRect::MakeLTRB(0, 0, size.width / 2, size.height / 2),
774  flutter::DlFilterMode::kNearest, nullptr);
775  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
776 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [237/419]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawNinePatchImageCenterHeightBiggerThanDest   
)

Definition at line 747 of file dl_unittests.cc.

747  {
748  // Edge case, the height of the corners does not leave any room for the
749  // center slice. The center (across the horizontal axis) is folded out of the
750  // resulting image.
751  auto texture = CreateTextureForFixture("embarcadero.jpg");
752  flutter::DisplayListBuilder builder;
753  auto size = texture->GetSize();
754  builder.DrawImageNine(
755  DlImageImpeller::Make(texture),
756  SkIRect::MakeLTRB(size.width / 4, size.height / 4, size.width * 3 / 4,
757  size.height * 3 / 4),
758  SkRect::MakeLTRB(0, 0, size.width, size.height / 2),
759  flutter::DlFilterMode::kNearest, nullptr);
760  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
761 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [238/419]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawNinePatchImageCenterWidthBiggerThanDest   
)

Definition at line 731 of file dl_unittests.cc.

731  {
732  // Edge case, the width of the corners does not leave any room for the
733  // center slice. The center (across the vertical axis) is folded out of the
734  // resulting image.
735  auto texture = CreateTextureForFixture("embarcadero.jpg");
736  flutter::DisplayListBuilder builder;
737  auto size = texture->GetSize();
738  builder.DrawImageNine(
739  DlImageImpeller::Make(texture),
740  SkIRect::MakeLTRB(size.width / 4, size.height / 4, size.width * 3 / 4,
741  size.height * 3 / 4),
742  SkRect::MakeLTRB(0, 0, size.width / 2, size.height),
743  flutter::DlFilterMode::kNearest, nullptr);
744  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
745 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [239/419]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawNinePatchImageCornersScaledDown   
)

Definition at line 778 of file dl_unittests.cc.

778  {
779  // Edge case, there is not enough room for the corners to be drawn
780  // without scaling them down.
781  auto texture = CreateTextureForFixture("embarcadero.jpg");
782  flutter::DisplayListBuilder builder;
783  auto size = texture->GetSize();
784  builder.DrawImageNine(
785  DlImageImpeller::Make(texture),
786  SkIRect::MakeLTRB(size.width / 4, size.height / 4, size.width * 3 / 4,
787  size.height * 3 / 4),
788  SkRect::MakeLTRB(0, 0, size.width / 4, size.height / 4),
789  flutter::DlFilterMode::kNearest, nullptr);
790  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
791 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [240/419]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawPaintWithColorSource   
)

Definition at line 1214 of file dl_unittests.cc.

1214  {
1215  const flutter::DlColor colors[2] = {
1216  flutter::DlColor(0xFFF44336),
1217  flutter::DlColor(0xFF2196F3),
1218  };
1219  const float stops[2] = {0.0, 1.0};
1220  flutter::DlPaint paint;
1221  flutter::DisplayListBuilder builder;
1222  auto clip_bounds = SkRect::MakeWH(300.0, 300.0);
1223  builder.Save();
1224  builder.Translate(100, 100);
1225  builder.ClipRect(clip_bounds, flutter::DlCanvas::ClipOp::kIntersect, false);
1226  auto linear =
1227  flutter::DlColorSource::MakeLinear({0.0, 0.0}, {100.0, 100.0}, 2, colors,
1228  stops, flutter::DlTileMode::kRepeat);
1229  paint.setColorSource(linear);
1230  builder.DrawPaint(paint);
1231  builder.Restore();
1232 
1233  builder.Save();
1234  builder.Translate(500, 100);
1235  builder.ClipRect(clip_bounds, flutter::DlCanvas::ClipOp::kIntersect, false);
1236  auto radial = flutter::DlColorSource::MakeRadial(
1237  {100.0, 100.0}, 100.0, 2, colors, stops, flutter::DlTileMode::kRepeat);
1238  paint.setColorSource(radial);
1239  builder.DrawPaint(paint);
1240  builder.Restore();
1241 
1242  builder.Save();
1243  builder.Translate(100, 500);
1244  builder.ClipRect(clip_bounds, flutter::DlCanvas::ClipOp::kIntersect, false);
1245  auto sweep =
1246  flutter::DlColorSource::MakeSweep({100.0, 100.0}, 180.0, 270.0, 2, colors,
1247  stops, flutter::DlTileMode::kRepeat);
1248  paint.setColorSource(sweep);
1249  builder.DrawPaint(paint);
1250  builder.Restore();
1251 
1252  builder.Save();
1253  builder.Translate(500, 500);
1254  builder.ClipRect(clip_bounds, flutter::DlCanvas::ClipOp::kIntersect, false);
1255  auto texture = CreateTextureForFixture("table_mountain_nx.png");
1256  auto image = std::make_shared<flutter::DlImageColorSource>(
1257  DlImageImpeller::Make(texture), flutter::DlTileMode::kRepeat,
1258  flutter::DlTileMode::kRepeat);
1259  paint.setColorSource(image);
1260  builder.DrawPaint(paint);
1261  builder.Restore();
1262 
1263  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1264 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [241/419]

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

Definition at line 805 of file dl_unittests.cc.

805  {
806  flutter::DisplayListBuilder builder;
807  SkPoint points[7] = {
808  {0, 0}, //
809  {100, 100}, //
810  {100, 0}, //
811  {0, 100}, //
812  {0, 0}, //
813  {48, 48}, //
814  {52, 52}, //
815  };
816  std::vector<flutter::DlStrokeCap> caps = {
817  flutter::DlStrokeCap::kButt,
818  flutter::DlStrokeCap::kRound,
819  flutter::DlStrokeCap::kSquare,
820  };
821  flutter::DlPaint paint =
822  flutter::DlPaint() //
823  .setColor(flutter::DlColor::kYellow().withAlpha(127)) //
824  .setStrokeWidth(20);
825  builder.Translate(50, 50);
826  for (auto cap : caps) {
827  paint.setStrokeCap(cap);
828  builder.Save();
829  builder.DrawPoints(flutter::DlCanvas::PointMode::kPoints, 7, points, paint);
830  builder.Translate(150, 0);
831  builder.DrawPoints(flutter::DlCanvas::PointMode::kLines, 5, points, paint);
832  builder.Translate(150, 0);
833  builder.DrawPoints(flutter::DlCanvas::PointMode::kPolygon, 5, points,
834  paint);
835  builder.Restore();
836  builder.Translate(0, 150);
837  }
838  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
839 }

◆ TEST_P() [242/419]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawRect   
)

Definition at line 49 of file dl_unittests.cc.

49  {
50  flutter::DisplayListBuilder builder;
51  builder.DrawRect(SkRect::MakeXYWH(10, 10, 100, 100),
52  flutter::DlPaint(flutter::DlColor::kBlue()));
53  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
54 }

◆ TEST_P() [243/419]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawRectWithLinearToSrgbColorFilter   
)

Definition at line 1198 of file dl_unittests.cc.

1198  {
1199  flutter::DlPaint paint;
1200  paint.setColor(flutter::DlColor(0xFF2196F3).withAlpha(128));
1201  flutter::DisplayListBuilder builder;
1202  paint.setColorFilter(
1203  flutter::DlLinearToSrgbGammaColorFilter::kInstance.get());
1204  builder.DrawRect(SkRect::MakeXYWH(0, 0, 200, 200), paint);
1205  builder.Translate(0, 200);
1206 
1207  paint.setColorFilter(
1208  flutter::DlSrgbToLinearGammaColorFilter::kInstance.get());
1209  builder.DrawRect(SkRect::MakeXYWH(0, 0, 200, 200), paint);
1210 
1211  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1212 }

◆ TEST_P() [244/419]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawShadow   
)

Definition at line 864 of file dl_unittests.cc.

864  {
865  flutter::DisplayListBuilder builder;
866  flutter::DlPaint paint;
867 
868  auto content_scale = GetContentScale() * 0.8;
869  builder.Scale(content_scale.x, content_scale.y);
870 
871  constexpr size_t star_spikes = 5;
872  constexpr SkScalar half_spike_rotation = kPi / star_spikes;
873  constexpr SkScalar radius = 40;
874  constexpr SkScalar spike_size = 10;
875  constexpr SkScalar outer_radius = radius + spike_size;
876  constexpr SkScalar inner_radius = radius - spike_size;
877  std::array<SkPoint, star_spikes * 2> star;
878  for (size_t i = 0; i < star_spikes; i++) {
879  const SkScalar rotation = half_spike_rotation * i * 2;
880  star[i * 2] = SkPoint::Make(50 + std::sin(rotation) * outer_radius,
881  50 - std::cos(rotation) * outer_radius);
882  star[i * 2 + 1] = SkPoint::Make(
883  50 + std::sin(rotation + half_spike_rotation) * inner_radius,
884  50 - std::cos(rotation + half_spike_rotation) * inner_radius);
885  }
886 
887  std::array<SkPath, 4> paths = {
888  SkPath{}.addRect(SkRect::MakeXYWH(0, 0, 200, 100)),
889  SkPath{}.addRRect(
890  SkRRect::MakeRectXY(SkRect::MakeXYWH(20, 0, 200, 100), 30, 30)),
891  SkPath{}.addCircle(100, 50, 50),
892  SkPath{}.addPoly(star.data(), star.size(), true),
893  };
894  paint.setColor(flutter::DlColor::kWhite());
895  builder.DrawPaint(paint);
896  paint.setColor(flutter::DlColor::kCyan());
897  builder.Translate(100, 50);
898  for (size_t x = 0; x < paths.size(); x++) {
899  builder.Save();
900  for (size_t y = 0; y < 6; y++) {
901  builder.DrawShadow(paths[x], flutter::DlColor::kBlack(), 3 + y * 8, false,
902  1);
903  builder.DrawPath(paths[x], paint);
904  builder.Translate(0, 150);
905  }
906  builder.Restore();
907  builder.Translate(250, 0);
908  }
909 
910  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
911 }

References impeller::kPi.

◆ TEST_P() [245/419]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawStrokedText   
)

Definition at line 466 of file dl_unittests.cc.

466  {
467  flutter::DisplayListBuilder builder;
468  flutter::DlPaint paint;
469 
470  paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
471  paint.setColor(flutter::DlColor::kRed());
472  builder.DrawTextBlob(
473  SkTextBlob::MakeFromString("stoked about stroked text", CreateTestFont()),
474  250, 250, paint);
475 
476  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
477 }

◆ TEST_P() [246/419]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawTextBlob   
)

Definition at line 56 of file dl_unittests.cc.

56  {
57  flutter::DisplayListBuilder builder;
58  builder.DrawTextBlob(SkTextBlob::MakeFromString("Hello", CreateTestFont()),
59  100, 100, flutter::DlPaint(flutter::DlColor::kBlue()));
60  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
61 }

◆ TEST_P() [247/419]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawTextBlobWithGradient   
)

Definition at line 63 of file dl_unittests.cc.

63  {
64  flutter::DisplayListBuilder builder;
65 
66  std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
67  flutter::DlColor::kRed()};
68  const float stops[2] = {0.0, 1.0};
69 
70  auto linear = flutter::DlColorSource::MakeLinear({0.0, 0.0}, {300.0, 300.0},
71  2, colors.data(), stops,
72  flutter::DlTileMode::kClamp);
73  flutter::DlPaint paint;
74  paint.setColorSource(linear);
75 
76  builder.DrawTextBlob(
77  SkTextBlob::MakeFromString("Hello World", CreateTestFont()), 100, 100,
78  paint);
79  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
80 }

◆ TEST_P() [248/419]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawTextWithSaveLayer   
)

Definition at line 82 of file dl_unittests.cc.

82  {
83  flutter::DisplayListBuilder builder;
84  builder.DrawTextBlob(SkTextBlob::MakeFromString("Hello", CreateTestFont()),
85  100, 100, flutter::DlPaint(flutter::DlColor::kRed()));
86 
87  flutter::DlPaint save_paint;
88  float alpha = 0.5;
89  save_paint.setAlpha(static_cast<uint8_t>(255 * alpha));
90  builder.SaveLayer(nullptr, &save_paint);
91  builder.DrawTextBlob(SkTextBlob::MakeFromString("Hello with half alpha",
92  CreateTestFontOfSize(100)),
93  100, 300, flutter::DlPaint(flutter::DlColor::kRed()));
94  builder.Restore();
95  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
96 }

◆ TEST_P() [249/419]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithBlendColorFilter   
)

Definition at line 518 of file dl_unittests.cc.

518  {
519  auto texture = CreateTextureForFixture("embarcadero.jpg");
520  flutter::DisplayListBuilder builder;
521  flutter::DlPaint paint;
522 
523  // Pipeline blended image.
524  {
525  auto filter = flutter::DlBlendColorFilter(flutter::DlColor::kYellow(),
526  flutter::DlBlendMode::kModulate);
527  paint.setColorFilter(&filter);
528  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
529  flutter::DlImageSampling::kNearestNeighbor, &paint);
530  }
531 
532  // Advanced blended image.
533  {
534  auto filter = flutter::DlBlendColorFilter(flutter::DlColor::kRed(),
535  flutter::DlBlendMode::kScreen);
536  paint.setColorFilter(&filter);
537  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(250, 250),
538  flutter::DlImageSampling::kNearestNeighbor, &paint);
539  }
540 
541  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
542 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [250/419]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithColorFilterImageFilter   
)

Definition at line 544 of file dl_unittests.cc.

544  {
545  const float invert_color_matrix[20] = {
546  -1, 0, 0, 0, 1, //
547  0, -1, 0, 0, 1, //
548  0, 0, -1, 0, 1, //
549  0, 0, 0, 1, 0, //
550  };
551  auto texture = CreateTextureForFixture("boston.jpg");
552  flutter::DisplayListBuilder builder;
553  flutter::DlPaint paint;
554 
555  auto color_filter =
556  std::make_shared<flutter::DlMatrixColorFilter>(invert_color_matrix);
557  auto image_filter =
558  std::make_shared<flutter::DlColorFilterImageFilter>(color_filter);
559 
560  paint.setImageFilter(image_filter.get());
561  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
562  flutter::DlImageSampling::kNearestNeighbor, &paint);
563 
564  builder.Translate(0, 700);
565  paint.setColorFilter(color_filter.get());
566  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
567  flutter::DlImageSampling::kNearestNeighbor, &paint);
568  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
569 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [251/419]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithComposeImageFilter   
)

Definition at line 596 of file dl_unittests.cc.

596  {
597  auto texture = CreateTextureForFixture("boston.jpg");
598  flutter::DisplayListBuilder builder;
599  flutter::DlPaint paint;
600 
601  auto dilate = std::make_shared<flutter::DlDilateImageFilter>(10.0, 10.0);
602  auto erode = std::make_shared<flutter::DlErodeImageFilter>(10.0, 10.0);
603  auto open = std::make_shared<flutter::DlComposeImageFilter>(dilate, erode);
604  auto close = std::make_shared<flutter::DlComposeImageFilter>(erode, dilate);
605 
606  paint.setImageFilter(open.get());
607  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
608  flutter::DlImageSampling::kNearestNeighbor, &paint);
609  builder.Translate(0, 700);
610  paint.setImageFilter(close.get());
611  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
612  flutter::DlImageSampling::kNearestNeighbor, &paint);
613  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
614 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [252/419]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithImageBlurFilter   
)

Definition at line 571 of file dl_unittests.cc.

571  {
572  auto texture = CreateTextureForFixture("embarcadero.jpg");
573 
574  auto callback = [&]() {
575  static float sigma[] = {10, 10};
576 
577  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
578  ImGui::SliderFloat2("Sigma", sigma, 0, 100);
579  ImGui::End();
580 
581  flutter::DisplayListBuilder builder;
582  flutter::DlPaint paint;
583 
584  auto filter = flutter::DlBlurImageFilter(sigma[0], sigma[1],
585  flutter::DlTileMode::kClamp);
586  paint.setImageFilter(&filter);
587  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(200, 200),
588  flutter::DlImageSampling::kNearestNeighbor, &paint);
589 
590  return builder.Build();
591  };
592 
593  ASSERT_TRUE(OpenPlaygroundHere(callback));
594 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [253/419]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithMaskBlur   
)

Definition at line 430 of file dl_unittests.cc.

430  {
431  auto texture = CreateTextureForFixture("embarcadero.jpg");
432  flutter::DisplayListBuilder builder;
433  flutter::DlPaint paint;
434 
435  // Mask blurred image.
436  {
437  auto filter =
438  flutter::DlBlurMaskFilter(flutter::DlBlurStyle::kNormal, 10.0f);
439  paint.setMaskFilter(&filter);
440  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
441  flutter::DlImageSampling::kNearestNeighbor, &paint);
442  }
443 
444  // Mask blurred filled path.
445  {
446  paint.setColor(flutter::DlColor::kYellow());
447  auto filter =
448  flutter::DlBlurMaskFilter(flutter::DlBlurStyle::kOuter, 10.0f);
449  paint.setMaskFilter(&filter);
450  builder.DrawArc(SkRect::MakeXYWH(410, 110, 100, 100), 45, 270, true, paint);
451  }
452 
453  // Mask blurred text.
454  {
455  auto filter =
456  flutter::DlBlurMaskFilter(flutter::DlBlurStyle::kSolid, 10.0f);
457  paint.setMaskFilter(&filter);
458  builder.DrawTextBlob(
459  SkTextBlob::MakeFromString("Testing", CreateTestFont()), 220, 170,
460  paint);
461  }
462 
463  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
464 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [254/419]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithMatrixFilter   
)

Definition at line 1038 of file dl_unittests.cc.

1038  {
1039  auto boston = CreateTextureForFixture("boston.jpg");
1040 
1041  auto callback = [&]() {
1042  static int selected_matrix_type = 0;
1043  const char* matrix_type_names[] = {"Matrix", "Local Matrix"};
1044 
1045  static float ctm_translation[2] = {200, 200};
1046  static float ctm_scale[2] = {0.65, 0.65};
1047  static float ctm_skew[2] = {0, 0};
1048 
1049  static bool enable = true;
1050  static float translation[2] = {100, 100};
1051  static float scale[2] = {0.8, 0.8};
1052  static float skew[2] = {0.2, 0.2};
1053 
1054  static bool enable_savelayer = true;
1055 
1056  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1057  {
1058  ImGui::Combo("Filter type", &selected_matrix_type, matrix_type_names,
1059  sizeof(matrix_type_names) / sizeof(char*));
1060 
1061  ImGui::TextWrapped("Current Transform");
1062  ImGui::SliderFloat2("CTM Translation", ctm_translation, 0, 1000);
1063  ImGui::SliderFloat2("CTM Scale", ctm_scale, 0, 3);
1064  ImGui::SliderFloat2("CTM Skew", ctm_skew, -3, 3);
1065 
1066  ImGui::TextWrapped(
1067  "MatrixFilter and LocalMatrixFilter modify the CTM in the same way. "
1068  "The only difference is that MatrixFilter doesn't affect the effect "
1069  "transform, whereas LocalMatrixFilter does.");
1070  // Note: See this behavior in:
1071  // https://fiddle.skia.org/c/6cbb551ab36d06f163db8693972be954
1072  ImGui::Checkbox("Enable", &enable);
1073  ImGui::SliderFloat2("Filter Translation", translation, 0, 1000);
1074  ImGui::SliderFloat2("Filter Scale", scale, 0, 3);
1075  ImGui::SliderFloat2("Filter Skew", skew, -3, 3);
1076 
1077  ImGui::TextWrapped(
1078  "Rendering the filtered image within a layer can expose bounds "
1079  "issues. If the rendered image gets cut off when this setting is "
1080  "enabled, there's a coverage bug in the filter.");
1081  ImGui::Checkbox("Render in layer", &enable_savelayer);
1082  }
1083  ImGui::End();
1084 
1085  flutter::DisplayListBuilder builder;
1086  flutter::DlPaint paint;
1087 
1088  if (enable_savelayer) {
1089  builder.SaveLayer(nullptr, nullptr);
1090  }
1091  {
1092  auto content_scale = GetContentScale();
1093  builder.Scale(content_scale.x, content_scale.y);
1094 
1095  // Set the current transform
1096  auto ctm_matrix =
1097  SkMatrix::MakeAll(ctm_scale[0], ctm_skew[0], ctm_translation[0], //
1098  ctm_skew[1], ctm_scale[1], ctm_translation[1], //
1099  0, 0, 1);
1100  builder.Transform(ctm_matrix);
1101 
1102  // Set the matrix filter
1103  auto filter_matrix =
1104  SkMatrix::MakeAll(scale[0], skew[0], translation[0], //
1105  skew[1], scale[1], translation[1], //
1106  0, 0, 1);
1107 
1108  if (enable) {
1109  switch (selected_matrix_type) {
1110  case 0: {
1111  auto filter = flutter::DlMatrixImageFilter(
1112  filter_matrix, flutter::DlImageSampling::kLinear);
1113  paint.setImageFilter(&filter);
1114  break;
1115  }
1116  case 1: {
1117  auto internal_filter =
1118  flutter::DlBlurImageFilter(10, 10, flutter::DlTileMode::kDecal)
1119  .shared();
1120  auto filter = flutter::DlLocalMatrixImageFilter(filter_matrix,
1121  internal_filter);
1122  paint.setImageFilter(&filter);
1123  break;
1124  }
1125  }
1126  }
1127 
1128  builder.DrawImage(DlImageImpeller::Make(boston), {},
1129  flutter::DlImageSampling::kLinear, &paint);
1130  }
1131  if (enable_savelayer) {
1132  builder.Restore();
1133  }
1134 
1135  return builder.Build();
1136  };
1137 
1138  ASSERT_TRUE(OpenPlaygroundHere(callback));
1139 }

References impeller::DlImageImpeller::Make(), and scale.

◆ TEST_P() [255/419]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithMatrixFilterWhenSavingLayer   
)

Definition at line 1141 of file dl_unittests.cc.

1141  {
1142  auto callback = [&]() {
1143  static float translation[2] = {0, 0};
1144  static bool enable_save_layer = true;
1145 
1146  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1147  ImGui::SliderFloat2("Translation", translation, -130, 130);
1148  ImGui::Checkbox("Enable save layer", &enable_save_layer);
1149  ImGui::End();
1150 
1151  flutter::DisplayListBuilder builder;
1152  builder.Save();
1153  builder.Scale(2.0, 2.0);
1154  flutter::DlPaint paint;
1155  paint.setColor(flutter::DlColor::kYellow());
1156  builder.DrawRect(SkRect::MakeWH(300, 300), paint);
1157  paint.setStrokeWidth(1.0);
1158  paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
1159  paint.setColor(flutter::DlColor::kBlack().withAlpha(0x80));
1160  builder.DrawLine(SkPoint::Make(150, 0), SkPoint::Make(150, 300), paint);
1161  builder.DrawLine(SkPoint::Make(0, 150), SkPoint::Make(300, 150), paint);
1162 
1163  flutter::DlPaint save_paint;
1164  SkRect bounds = SkRect::MakeXYWH(100, 100, 100, 100);
1165  SkMatrix translate_matrix =
1166  SkMatrix::Translate(translation[0], translation[1]);
1167  if (enable_save_layer) {
1168  auto filter = flutter::DlMatrixImageFilter(
1169  translate_matrix, flutter::DlImageSampling::kNearestNeighbor);
1170  save_paint.setImageFilter(filter.shared());
1171  builder.SaveLayer(&bounds, &save_paint);
1172  } else {
1173  builder.Save();
1174  builder.Transform(translate_matrix);
1175  }
1176 
1177  SkMatrix filter_matrix = SkMatrix::I();
1178  filter_matrix.postTranslate(-150, -150);
1179  filter_matrix.postScale(0.2f, 0.2f);
1180  filter_matrix.postTranslate(150, 150);
1181  auto filter = flutter::DlMatrixImageFilter(
1182  filter_matrix, flutter::DlImageSampling::kNearestNeighbor);
1183 
1184  save_paint.setImageFilter(filter.shared());
1185 
1186  builder.SaveLayer(&bounds, &save_paint);
1187  flutter::DlPaint paint2;
1188  paint2.setColor(flutter::DlColor::kBlue());
1189  builder.DrawRect(bounds, paint2);
1190  builder.Restore();
1191  builder.Restore();
1192  return builder.Build();
1193  };
1194 
1195  ASSERT_TRUE(OpenPlaygroundHere(callback));
1196 }

◆ TEST_P() [256/419]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithOddPathWinding   
)

Definition at line 386 of file dl_unittests.cc.

386  {
387  flutter::DisplayListBuilder builder;
388  flutter::DlPaint paint;
389 
390  paint.setColor(flutter::DlColor::kRed());
391  paint.setDrawStyle(flutter::DlDrawStyle::kFill);
392 
393  builder.Translate(300, 300);
394  SkPath path;
395  path.setFillType(SkPathFillType::kEvenOdd);
396  path.addCircle(0, 0, 100);
397  path.addCircle(0, 0, 50);
398  builder.DrawPath(path, paint);
399 
400  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
401 }

◆ TEST_P() [257/419]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawZeroLengthLine   
)

Definition at line 841 of file dl_unittests.cc.

841  {
842  flutter::DisplayListBuilder builder;
843  std::vector<flutter::DlStrokeCap> caps = {
844  flutter::DlStrokeCap::kButt,
845  flutter::DlStrokeCap::kRound,
846  flutter::DlStrokeCap::kSquare,
847  };
848  flutter::DlPaint paint =
849  flutter::DlPaint() //
850  .setColor(flutter::DlColor::kYellow().withAlpha(127)) //
851  .setDrawStyle(flutter::DlDrawStyle::kStroke) //
852  .setStrokeCap(flutter::DlStrokeCap::kButt) //
853  .setStrokeWidth(20);
854  SkPath path = SkPath().addPoly({{150, 50}, {150, 50}}, false);
855  for (auto cap : caps) {
856  paint.setStrokeCap(cap);
857  builder.DrawLine({50, 50}, {50, 50}, paint);
858  builder.DrawPath(path, paint);
859  builder.Translate(0, 150);
860  }
861  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
862 }

◆ TEST_P() [258/419]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawZeroWidthLine   
)

Definition at line 1004 of file dl_unittests.cc.

1004  {
1005  flutter::DisplayListBuilder builder;
1006  std::vector<flutter::DlStrokeCap> caps = {
1007  flutter::DlStrokeCap::kButt,
1008  flutter::DlStrokeCap::kRound,
1009  flutter::DlStrokeCap::kSquare,
1010  };
1011  flutter::DlPaint paint = //
1012  flutter::DlPaint() //
1013  .setColor(flutter::DlColor::kWhite()) //
1014  .setDrawStyle(flutter::DlDrawStyle::kStroke) //
1015  .setStrokeWidth(0);
1016  flutter::DlPaint outline_paint = //
1017  flutter::DlPaint() //
1018  .setColor(flutter::DlColor::kYellow()) //
1019  .setDrawStyle(flutter::DlDrawStyle::kStroke) //
1020  .setStrokeCap(flutter::DlStrokeCap::kSquare) //
1021  .setStrokeWidth(1);
1022  SkPath path = SkPath().addPoly({{150, 50}, {160, 50}}, false);
1023  for (auto cap : caps) {
1024  paint.setStrokeCap(cap);
1025  builder.DrawLine({50, 50}, {60, 50}, paint);
1026  builder.DrawRect({45, 45, 65, 55}, outline_paint);
1027  builder.DrawLine({100, 50}, {100, 50}, paint);
1028  if (cap != flutter::DlStrokeCap::kButt) {
1029  builder.DrawRect({95, 45, 105, 55}, outline_paint);
1030  }
1031  builder.DrawPath(path, paint);
1032  builder.DrawRect(path.getBounds().makeOutset(5, 5), outline_paint);
1033  builder.Translate(0, 150);
1034  }
1035  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1036 }

◆ TEST_P() [259/419]

impeller::testing::TEST_P ( DisplayListTest  ,
ClipDrawRRectWithNonCircularRadii   
)

Definition at line 1598 of file dl_unittests.cc.

1598  {
1599  flutter::DisplayListBuilder builder;
1600 
1601  flutter::DlPaint fill_paint = //
1602  flutter::DlPaint() //
1603  .setColor(flutter::DlColor::kBlue()) //
1604  .setDrawStyle(flutter::DlDrawStyle::kFill) //
1605  .setStrokeWidth(10);
1606  flutter::DlPaint stroke_paint = //
1607  flutter::DlPaint() //
1608  .setColor(flutter::DlColor::kGreen()) //
1609  .setDrawStyle(flutter::DlDrawStyle::kStroke) //
1610  .setStrokeWidth(10);
1611 
1612  builder.DrawRRect(
1613  SkRRect::MakeRectXY(SkRect::MakeXYWH(500, 100, 300, 300), 120, 40),
1614  fill_paint);
1615  builder.DrawRRect(
1616  SkRRect::MakeRectXY(SkRect::MakeXYWH(500, 100, 300, 300), 120, 40),
1617  stroke_paint);
1618 
1619  builder.DrawRRect(
1620  SkRRect::MakeRectXY(SkRect::MakeXYWH(100, 500, 300, 300), 40, 120),
1621  fill_paint);
1622  builder.DrawRRect(
1623  SkRRect::MakeRectXY(SkRect::MakeXYWH(100, 500, 300, 300), 40, 120),
1624  stroke_paint);
1625 
1626  flutter::DlPaint reference_paint = //
1627  flutter::DlPaint() //
1628  .setColor(flutter::DlColor::kMidGrey()) //
1629  .setDrawStyle(flutter::DlDrawStyle::kFill) //
1630  .setStrokeWidth(10);
1631 
1632  builder.DrawRRect(
1633  SkRRect::MakeRectXY(SkRect::MakeXYWH(500, 500, 300, 300), 40, 40),
1634  reference_paint);
1635  builder.DrawRRect(
1636  SkRRect::MakeRectXY(SkRect::MakeXYWH(100, 100, 300, 300), 120, 120),
1637  reference_paint);
1638 
1639  flutter::DlPaint clip_fill_paint = //
1640  flutter::DlPaint() //
1641  .setColor(flutter::DlColor::kCyan()) //
1642  .setDrawStyle(flutter::DlDrawStyle::kFill) //
1643  .setStrokeWidth(10);
1644 
1645  builder.Save();
1646  builder.ClipRRect(
1647  SkRRect::MakeRectXY(SkRect::MakeXYWH(900, 100, 300, 300), 120, 40));
1648  builder.DrawPaint(clip_fill_paint);
1649  builder.Restore();
1650 
1651  builder.Save();
1652  builder.ClipRRect(
1653  SkRRect::MakeRectXY(SkRect::MakeXYWH(100, 900, 300, 300), 40, 120));
1654  builder.DrawPaint(clip_fill_paint);
1655  builder.Restore();
1656 
1657  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1658 }

◆ TEST_P() [260/419]

impeller::testing::TEST_P ( DisplayListTest  ,
DispatcherDoesNotCullPerspectiveTransformedChildDisplayLists   
)

Definition at line 913 of file dl_unittests.cc.

914  {
915  // Regression test for https://github.com/flutter/flutter/issues/130613
916  flutter::DisplayListBuilder sub_builder(true);
917  sub_builder.DrawRect(SkRect::MakeXYWH(0, 0, 50, 50),
918  flutter::DlPaint(flutter::DlColor::kRed()));
919  auto display_list = sub_builder.Build();
920 
921  DlDispatcher dispatcher(Rect::MakeLTRB(0, 0, 2400, 1800));
922  dispatcher.scale(2.0, 2.0);
923  dispatcher.translate(-93.0, 0.0);
924  // clang-format off
925  dispatcher.transformFullPerspective(
926  0.8, -0.2, -0.1, -0.0,
927  0.0, 1.0, 0.0, 0.0,
928  1.4, 1.3, 1.0, 0.0,
929  63.2, 65.3, 48.6, 1.1
930  );
931  // clang-format on
932  dispatcher.translate(35.0, 75.0);
933  dispatcher.drawDisplayList(display_list, 1.0f);
934  auto picture = dispatcher.EndRecordingAsPicture();
935 
936  bool found = false;
937  picture.pass->IterateAllEntities([&found](Entity& entity) {
938  if (std::static_pointer_cast<SolidColorContents>(entity.GetContents())
939  ->GetColor() == Color::Red()) {
940  found = true;
941  return false;
942  }
943 
944  return true;
945  });
946  EXPECT_TRUE(found);
947 }

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

impeller::testing::TEST_P ( DisplayListTest  ,
DrawPaintIgnoresMaskFilter   
)

Definition at line 1837 of file dl_unittests.cc.

1837  {
1838  flutter::DisplayListBuilder builder;
1839  builder.DrawPaint(flutter::DlPaint().setColor(flutter::DlColor::kWhite()));
1840 
1841  auto filter = flutter::DlBlurMaskFilter(flutter::DlBlurStyle::kNormal, 10.0f);
1842  builder.DrawCircle({300, 300}, 200,
1843  flutter::DlPaint().setMaskFilter(&filter));
1844 
1845  std::vector<flutter::DlColor> colors = {flutter::DlColor::kGreen(),
1846  flutter::DlColor::kGreen()};
1847  const float stops[2] = {0.0, 1.0};
1848  auto linear = flutter::DlColorSource::MakeLinear(
1849  {100.0, 100.0}, {300.0, 300.0}, 2, colors.data(), stops,
1850  flutter::DlTileMode::kRepeat);
1851  flutter::DlPaint blend_paint =
1852  flutter::DlPaint() //
1853  .setColorSource(linear) //
1854  .setBlendMode(flutter::DlBlendMode::kScreen);
1855  builder.DrawPaint(blend_paint);
1856 
1857  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1858 }

◆ TEST_P() [262/419]

impeller::testing::TEST_P ( DisplayListTest  ,
DrawShapes   
)

Definition at line 1560 of file dl_unittests.cc.

1560  {
1561  flutter::DisplayListBuilder builder;
1562  std::vector<flutter::DlStrokeJoin> joins = {
1563  flutter::DlStrokeJoin::kBevel,
1564  flutter::DlStrokeJoin::kRound,
1565  flutter::DlStrokeJoin::kMiter,
1566  };
1567  flutter::DlPaint paint = //
1568  flutter::DlPaint() //
1569  .setColor(flutter::DlColor::kWhite()) //
1570  .setDrawStyle(flutter::DlDrawStyle::kFill) //
1571  .setStrokeWidth(10);
1572  flutter::DlPaint stroke_paint = //
1573  flutter::DlPaint() //
1574  .setColor(flutter::DlColor::kWhite()) //
1575  .setDrawStyle(flutter::DlDrawStyle::kStroke) //
1576  .setStrokeWidth(10);
1577  SkPath path = SkPath().addPoly({{150, 50}, {160, 50}}, false);
1578 
1579  builder.Translate(300, 50);
1580  builder.Scale(0.8, 0.8);
1581  for (auto join : joins) {
1582  paint.setStrokeJoin(join);
1583  stroke_paint.setStrokeJoin(join);
1584  builder.DrawRect(SkRect::MakeXYWH(0, 0, 100, 100), paint);
1585  builder.DrawRect(SkRect::MakeXYWH(0, 150, 100, 100), stroke_paint);
1586  builder.DrawRRect(
1587  SkRRect::MakeRectXY(SkRect::MakeXYWH(150, 0, 100, 100), 30, 30), paint);
1588  builder.DrawRRect(
1589  SkRRect::MakeRectXY(SkRect::MakeXYWH(150, 150, 100, 100), 30, 30),
1590  stroke_paint);
1591  builder.DrawCircle({350, 50}, 50, paint);
1592  builder.DrawCircle({350, 200}, 50, stroke_paint);
1593  builder.Translate(0, 300);
1594  }
1595  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1596 }

◆ TEST_P() [263/419]

impeller::testing::TEST_P ( DisplayListTest  ,
DrawVerticesBlendModes   
)

Definition at line 1660 of file dl_unittests.cc.

1660  {
1661  std::vector<const char*> blend_mode_names;
1662  std::vector<flutter::DlBlendMode> blend_mode_values;
1663  {
1664  const std::vector<std::tuple<const char*, flutter::DlBlendMode>> blends = {
1665  // Pipeline blends (Porter-Duff alpha compositing)
1666  {"Clear", flutter::DlBlendMode::kClear},
1667  {"Source", flutter::DlBlendMode::kSrc},
1668  {"Destination", flutter::DlBlendMode::kDst},
1669  {"SourceOver", flutter::DlBlendMode::kSrcOver},
1670  {"DestinationOver", flutter::DlBlendMode::kDstOver},
1671  {"SourceIn", flutter::DlBlendMode::kSrcIn},
1672  {"DestinationIn", flutter::DlBlendMode::kDstIn},
1673  {"SourceOut", flutter::DlBlendMode::kSrcOut},
1674  {"DestinationOut", flutter::DlBlendMode::kDstOut},
1675  {"SourceATop", flutter::DlBlendMode::kSrcATop},
1676  {"DestinationATop", flutter::DlBlendMode::kDstATop},
1677  {"Xor", flutter::DlBlendMode::kXor},
1678  {"Plus", flutter::DlBlendMode::kPlus},
1679  {"Modulate", flutter::DlBlendMode::kModulate},
1680  // Advanced blends (color component blends)
1681  {"Screen", flutter::DlBlendMode::kScreen},
1682  {"Overlay", flutter::DlBlendMode::kOverlay},
1683  {"Darken", flutter::DlBlendMode::kDarken},
1684  {"Lighten", flutter::DlBlendMode::kLighten},
1685  {"ColorDodge", flutter::DlBlendMode::kColorDodge},
1686  {"ColorBurn", flutter::DlBlendMode::kColorBurn},
1687  {"HardLight", flutter::DlBlendMode::kHardLight},
1688  {"SoftLight", flutter::DlBlendMode::kSoftLight},
1689  {"Difference", flutter::DlBlendMode::kDifference},
1690  {"Exclusion", flutter::DlBlendMode::kExclusion},
1691  {"Multiply", flutter::DlBlendMode::kMultiply},
1692  {"Hue", flutter::DlBlendMode::kHue},
1693  {"Saturation", flutter::DlBlendMode::kSaturation},
1694  {"Color", flutter::DlBlendMode::kColor},
1695  {"Luminosity", flutter::DlBlendMode::kLuminosity},
1696  };
1697  assert(blends.size() ==
1698  static_cast<size_t>(flutter::DlBlendMode::kLastMode) + 1);
1699  for (const auto& [name, mode] : blends) {
1700  blend_mode_names.push_back(name);
1701  blend_mode_values.push_back(mode);
1702  }
1703  }
1704 
1705  auto callback = [&]() {
1706  static int current_blend_index = 3;
1707  static float dst_alpha = 1;
1708  static float src_alpha = 1;
1709  static float color0[4] = {1.0f, 0.0f, 0.0f, 1.0f};
1710  static float color1[4] = {0.0f, 1.0f, 0.0f, 1.0f};
1711  static float color2[4] = {0.0f, 0.0f, 1.0f, 1.0f};
1712  static float src_color[4] = {1.0f, 1.0f, 1.0f, 1.0f};
1713 
1714  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1715  {
1716  ImGui::ListBox("Blending mode", &current_blend_index,
1717  blend_mode_names.data(), blend_mode_names.size());
1718  ImGui::SliderFloat("Source alpha", &src_alpha, 0, 1);
1719  ImGui::ColorEdit4("Color A", color0);
1720  ImGui::ColorEdit4("Color B", color1);
1721  ImGui::ColorEdit4("Color C", color2);
1722  ImGui::ColorEdit4("Source Color", src_color);
1723  ImGui::SliderFloat("Destination alpha", &dst_alpha, 0, 1);
1724  }
1725  ImGui::End();
1726 
1727  std::vector<SkPoint> positions = {SkPoint::Make(100, 300),
1728  SkPoint::Make(200, 100),
1729  SkPoint::Make(300, 300)};
1730  std::vector<flutter::DlColor> colors = {
1731  toColor(color0).modulateOpacity(dst_alpha),
1732  toColor(color1).modulateOpacity(dst_alpha),
1733  toColor(color2).modulateOpacity(dst_alpha)};
1734 
1735  auto vertices = flutter::DlVertices::Make(
1736  flutter::DlVertexMode::kTriangles, 3, positions.data(),
1737  /*texture_coordinates=*/nullptr, colors.data());
1738 
1739  flutter::DisplayListBuilder builder;
1740  flutter::DlPaint paint;
1741 
1742  paint.setColor(toColor(src_color).modulateOpacity(src_alpha));
1743  builder.DrawVertices(vertices, blend_mode_values[current_blend_index],
1744  paint);
1745  return builder.Build();
1746  };
1747 
1748  ASSERT_TRUE(OpenPlaygroundHere(callback));
1749 }

References impeller::kColor, and toColor().

◆ TEST_P() [264/419]

impeller::testing::TEST_P ( DisplayListTest  ,
DrawVerticesImageSourceWithTextureCoordinates   
)

Definition at line 1462 of file dl_unittests.cc.

1462  {
1463  auto texture = CreateTextureForFixture("embarcadero.jpg");
1464  auto dl_image = DlImageImpeller::Make(texture);
1465  std::vector<SkPoint> positions = {SkPoint::Make(100, 300),
1466  SkPoint::Make(200, 100),
1467  SkPoint::Make(300, 300)};
1468  std::vector<SkPoint> texture_coordinates = {
1469  SkPoint::Make(0, 0), SkPoint::Make(100, 200), SkPoint::Make(200, 100)};
1470 
1471  auto vertices = flutter::DlVertices::Make(
1472  flutter::DlVertexMode::kTriangles, 3, positions.data(),
1473  texture_coordinates.data(), /*colors=*/nullptr);
1474 
1475  flutter::DisplayListBuilder builder;
1476  flutter::DlPaint paint;
1477 
1478  auto image_source = flutter::DlImageColorSource(
1479  dl_image, flutter::DlTileMode::kRepeat, flutter::DlTileMode::kRepeat);
1480 
1481  paint.setColorSource(&image_source);
1482  builder.DrawVertices(vertices, flutter::DlBlendMode::kSrcOver, paint);
1483 
1484  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1485 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [265/419]

impeller::testing::TEST_P ( DisplayListTest  ,
DrawVerticesImageSourceWithTextureCoordinatesAndColorBlending   
)

Definition at line 1487 of file dl_unittests.cc.

1488  {
1489  auto texture = CreateTextureForFixture("embarcadero.jpg");
1490  auto dl_image = DlImageImpeller::Make(texture);
1491  std::vector<SkPoint> positions = {SkPoint::Make(100, 300),
1492  SkPoint::Make(200, 100),
1493  SkPoint::Make(300, 300)};
1494  std::vector<flutter::DlColor> colors = {flutter::DlColor::kWhite(),
1495  flutter::DlColor::kGreen(),
1496  flutter::DlColor::kWhite()};
1497  std::vector<SkPoint> texture_coordinates = {
1498  SkPoint::Make(0, 0), SkPoint::Make(100, 200), SkPoint::Make(200, 100)};
1499 
1500  auto vertices = flutter::DlVertices::Make(
1501  flutter::DlVertexMode::kTriangles, 3, positions.data(),
1502  texture_coordinates.data(), colors.data());
1503 
1504  flutter::DisplayListBuilder builder;
1505  flutter::DlPaint paint;
1506 
1507  auto image_source = flutter::DlImageColorSource(
1508  dl_image, flutter::DlTileMode::kRepeat, flutter::DlTileMode::kRepeat);
1509 
1510  paint.setColorSource(&image_source);
1511  builder.DrawVertices(vertices, flutter::DlBlendMode::kModulate, paint);
1512 
1513  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1514 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [266/419]

impeller::testing::TEST_P ( DisplayListTest  ,
DrawVerticesLinearGradientWithoutIndices   
)

Definition at line 1407 of file dl_unittests.cc.

1407  {
1408  std::vector<SkPoint> positions = {SkPoint::Make(100, 300),
1409  SkPoint::Make(200, 100),
1410  SkPoint::Make(300, 300)};
1411 
1412  auto vertices = flutter::DlVertices::Make(
1413  flutter::DlVertexMode::kTriangles, 3, positions.data(),
1414  /*texture_coordinates=*/nullptr, /*colors=*/nullptr);
1415 
1416  std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
1417  flutter::DlColor::kRed()};
1418  const float stops[2] = {0.0, 1.0};
1419 
1420  auto linear = flutter::DlColorSource::MakeLinear(
1421  {100.0, 100.0}, {300.0, 300.0}, 2, colors.data(), stops,
1422  flutter::DlTileMode::kRepeat);
1423 
1424  flutter::DisplayListBuilder builder;
1425  flutter::DlPaint paint;
1426 
1427  paint.setColorSource(linear);
1428  builder.DrawVertices(vertices, flutter::DlBlendMode::kSrcOver, paint);
1429 
1430  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1431 }

◆ TEST_P() [267/419]

impeller::testing::TEST_P ( DisplayListTest  ,
DrawVerticesLinearGradientWithTextureCoordinates   
)

Definition at line 1433 of file dl_unittests.cc.

1433  {
1434  std::vector<SkPoint> positions = {SkPoint::Make(100, 300),
1435  SkPoint::Make(200, 100),
1436  SkPoint::Make(300, 300)};
1437  std::vector<SkPoint> texture_coordinates = {SkPoint::Make(300, 100),
1438  SkPoint::Make(100, 200),
1439  SkPoint::Make(300, 300)};
1440 
1441  auto vertices = flutter::DlVertices::Make(
1442  flutter::DlVertexMode::kTriangles, 3, positions.data(),
1443  texture_coordinates.data(), /*colors=*/nullptr);
1444 
1445  std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
1446  flutter::DlColor::kRed()};
1447  const float stops[2] = {0.0, 1.0};
1448 
1449  auto linear = flutter::DlColorSource::MakeLinear(
1450  {100.0, 100.0}, {300.0, 300.0}, 2, colors.data(), stops,
1451  flutter::DlTileMode::kRepeat);
1452 
1453  flutter::DisplayListBuilder builder;
1454  flutter::DlPaint paint;
1455 
1456  paint.setColorSource(linear);
1457  builder.DrawVertices(vertices, flutter::DlBlendMode::kSrcOver, paint);
1458 
1459  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1460 }

◆ TEST_P() [268/419]

impeller::testing::TEST_P ( DisplayListTest  ,
DrawVerticesPremultipliesColors   
)

Definition at line 1536 of file dl_unittests.cc.

1536  {
1537  std::vector<SkPoint> positions = {
1538  SkPoint::Make(100, 300), SkPoint::Make(200, 100), SkPoint::Make(300, 300),
1539  SkPoint::Make(200, 500)};
1540  auto color = flutter::DlColor::kBlue().withAlpha(0x99);
1541  std::vector<uint16_t> indices = {0, 1, 2, 0, 2, 3};
1542  std::vector<flutter::DlColor> colors = {color, color, color, color};
1543 
1544  auto vertices = flutter::DlVertices::Make(
1545  flutter::DlVertexMode::kTriangles, positions.size(), positions.data(),
1546  /*texture_coordinates=*/nullptr, colors.data(), indices.size(),
1547  indices.data());
1548 
1549  flutter::DisplayListBuilder builder;
1550  flutter::DlPaint paint;
1551  paint.setBlendMode(flutter::DlBlendMode::kSrcOver);
1552  paint.setColor(flutter::DlColor::kRed());
1553 
1554  builder.DrawRect(SkRect::MakeLTRB(0, 0, 400, 400), paint);
1555  builder.DrawVertices(vertices, flutter::DlBlendMode::kDst, paint);
1556 
1557  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1558 }

◆ TEST_P() [269/419]

impeller::testing::TEST_P ( DisplayListTest  ,
DrawVerticesSolidColorTrianglesWithIndices   
)

Definition at line 1516 of file dl_unittests.cc.

1516  {
1517  std::vector<SkPoint> positions = {
1518  SkPoint::Make(100, 300), SkPoint::Make(200, 100), SkPoint::Make(300, 300),
1519  SkPoint::Make(200, 500)};
1520  std::vector<uint16_t> indices = {0, 1, 2, 0, 2, 3};
1521 
1522  auto vertices = flutter::DlVertices::Make(
1523  flutter::DlVertexMode::kTriangles, positions.size(), positions.data(),
1524  /*texture_coordinates=*/nullptr, /*colors=*/nullptr, indices.size(),
1525  indices.data());
1526 
1527  flutter::DisplayListBuilder builder;
1528  flutter::DlPaint paint;
1529 
1530  paint.setColor(flutter::DlColor::kWhite());
1531  builder.DrawVertices(vertices, flutter::DlBlendMode::kSrcOver, paint);
1532 
1533  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1534 }

◆ TEST_P() [270/419]

impeller::testing::TEST_P ( DisplayListTest  ,
DrawVerticesSolidColorTrianglesWithoutIndices   
)

Definition at line 1383 of file dl_unittests.cc.

1383  {
1384  // Use negative coordinates and then scale the transform by -1, -1 to make
1385  // sure coverage is taking the transform into account.
1386  std::vector<SkPoint> positions = {SkPoint::Make(-100, -300),
1387  SkPoint::Make(-200, -100),
1388  SkPoint::Make(-300, -300)};
1389  std::vector<flutter::DlColor> colors = {flutter::DlColor::kWhite(),
1390  flutter::DlColor::kGreen(),
1391  flutter::DlColor::kWhite()};
1392 
1393  auto vertices = flutter::DlVertices::Make(
1394  flutter::DlVertexMode::kTriangles, 3, positions.data(),
1395  /*texture_coordinates=*/nullptr, colors.data());
1396 
1397  flutter::DisplayListBuilder builder;
1398  flutter::DlPaint paint;
1399 
1400  paint.setColor(flutter::DlColor::kRed().modulateOpacity(0.5));
1401  builder.Scale(-1, -1);
1402  builder.DrawVertices(vertices, flutter::DlBlendMode::kSrcOver, paint);
1403 
1404  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1405 }

◆ TEST_P() [271/419]

impeller::testing::TEST_P ( DisplayListTest  ,
IgnoreMaskFilterWhenSavingLayer   
)

Definition at line 505 of file dl_unittests.cc.

505  {
506  auto texture = CreateTextureForFixture("embarcadero.jpg");
507  flutter::DisplayListBuilder builder;
508  auto filter = flutter::DlBlurMaskFilter(flutter::DlBlurStyle::kNormal, 10.0f);
509  flutter::DlPaint paint;
510  paint.setMaskFilter(&filter);
511  builder.SaveLayer(nullptr, &paint);
512  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
513  flutter::DlImageSampling::kNearestNeighbor);
514  builder.Restore();
515  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
516 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [272/419]

impeller::testing::TEST_P ( DisplayListTest  ,
MaskBlursApplyCorrectlyToColorSources   
)

Definition at line 1346 of file dl_unittests.cc.

1346  {
1347  auto blur_filter = std::make_shared<flutter::DlBlurMaskFilter>(
1348  flutter::DlBlurStyle::kNormal, 10);
1349 
1350  flutter::DisplayListBuilder builder;
1351 
1352  std::array<flutter::DlColor, 2> colors = {flutter::DlColor::kBlue(),
1353  flutter::DlColor::kGreen()};
1354  std::array<float, 2> stops = {0, 1};
1355  std::array<std::shared_ptr<flutter::DlColorSource>, 2> color_sources = {
1356  std::make_shared<flutter::DlColorColorSource>(flutter::DlColor::kWhite()),
1357  flutter::DlColorSource::MakeLinear(
1358  SkPoint::Make(0, 0), SkPoint::Make(100, 50), 2, colors.data(),
1359  stops.data(), flutter::DlTileMode::kClamp)};
1360 
1361  int offset = 100;
1362  for (const auto& color_source : color_sources) {
1363  flutter::DlPaint paint;
1364  paint.setColorSource(color_source);
1365  paint.setMaskFilter(blur_filter);
1366 
1367  paint.setDrawStyle(flutter::DlDrawStyle::kFill);
1368  builder.DrawRRect(
1369  SkRRect::MakeRectXY(SkRect::MakeXYWH(100, offset, 100, 50), 30, 30),
1370  paint);
1371  paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
1372  paint.setStrokeWidth(10);
1373  builder.DrawRRect(
1374  SkRRect::MakeRectXY(SkRect::MakeXYWH(300, offset, 100, 50), 30, 30),
1375  paint);
1376 
1377  offset += 100;
1378  }
1379 
1380  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1381 }

References offset.

◆ TEST_P() [273/419]

impeller::testing::TEST_P ( DisplayListTest  ,
NinePatchImagePrecision   
)

Definition at line 793 of file dl_unittests.cc.

793  {
794  // Draw a nine patch image with colored corners and verify that the corner
795  // color does not leak outside the intended region.
796  auto texture = CreateTextureForFixture("nine_patch_corners.png");
797  flutter::DisplayListBuilder builder;
798  builder.DrawImageNine(DlImageImpeller::Make(texture),
799  SkIRect::MakeXYWH(10, 10, 1, 1),
800  SkRect::MakeXYWH(0, 0, 200, 100),
801  flutter::DlFilterMode::kNearest, nullptr);
802  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
803 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [274/419]

impeller::testing::TEST_P ( DisplayListTest  ,
StrokedPathsDrawCorrectly   
)

Definition at line 213 of file dl_unittests.cc.

213  {
214  auto callback = [&]() {
215  flutter::DisplayListBuilder builder;
216  flutter::DlPaint paint;
217 
218  paint.setColor(flutter::DlColor::kRed());
219  paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
220 
221  static float stroke_width = 10.0f;
222  static int selected_stroke_type = 0;
223  static int selected_join_type = 0;
224  const char* stroke_types[] = {"Butte", "Round", "Square"};
225  const char* join_type[] = {"kMiter", "Round", "kBevel"};
226 
227  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
228  ImGui::Combo("Cap", &selected_stroke_type, stroke_types,
229  sizeof(stroke_types) / sizeof(char*));
230  ImGui::Combo("Join", &selected_join_type, join_type,
231  sizeof(join_type) / sizeof(char*));
232  ImGui::SliderFloat("Stroke Width", &stroke_width, 10.0f, 50.0f);
233  ImGui::End();
234 
235  flutter::DlStrokeCap cap;
236  flutter::DlStrokeJoin join;
237  switch (selected_stroke_type) {
238  case 0:
239  cap = flutter::DlStrokeCap::kButt;
240  break;
241  case 1:
242  cap = flutter::DlStrokeCap::kRound;
243  break;
244  case 2:
245  cap = flutter::DlStrokeCap::kSquare;
246  break;
247  default:
248  cap = flutter::DlStrokeCap::kButt;
249  break;
250  }
251  switch (selected_join_type) {
252  case 0:
253  join = flutter::DlStrokeJoin::kMiter;
254  break;
255  case 1:
256  join = flutter::DlStrokeJoin::kRound;
257  break;
258  case 2:
259  join = flutter::DlStrokeJoin::kBevel;
260  break;
261  default:
262  join = flutter::DlStrokeJoin::kMiter;
263  break;
264  }
265  paint.setStrokeCap(cap);
266  paint.setStrokeJoin(join);
267  paint.setStrokeWidth(stroke_width);
268 
269  // Make rendering better to watch.
270  builder.Scale(1.5f, 1.5f);
271 
272  // Rectangle
273  builder.Translate(100, 100);
274  builder.DrawRect(SkRect::MakeSize({100, 100}), paint);
275 
276  // Rounded rectangle
277  builder.Translate(150, 0);
278  builder.DrawRRect(SkRRect::MakeRectXY(SkRect::MakeSize({100, 50}), 10, 10),
279  paint);
280 
281  // Double rounded rectangle
282  builder.Translate(150, 0);
283  builder.DrawDRRect(
284  SkRRect::MakeRectXY(SkRect::MakeSize({100, 50}), 10, 10),
285  SkRRect::MakeRectXY(SkRect::MakeXYWH(10, 10, 80, 30), 10, 10), paint);
286 
287  // Contour with duplicate join points
288  {
289  builder.Translate(150, 0);
290  SkPath path;
291  path.moveTo(0, 0);
292  path.lineTo(0, 0);
293  path.lineTo({100, 0});
294  path.lineTo({100, 0});
295  path.lineTo({100, 100});
296  builder.DrawPath(path, paint);
297  }
298 
299  // Contour with duplicate start and end points
300 
301  // Line.
302  builder.Translate(200, 0);
303  {
304  builder.Save();
305 
306  SkPath line_path;
307  line_path.moveTo(0, 0);
308  line_path.moveTo(0, 0);
309  line_path.lineTo({0, 0});
310  line_path.lineTo({0, 0});
311  line_path.lineTo({50, 50});
312  line_path.lineTo({50, 50});
313  line_path.lineTo({100, 0});
314  line_path.lineTo({100, 0});
315  builder.DrawPath(line_path, paint);
316 
317  builder.Translate(0, 100);
318  builder.DrawPath(line_path, paint);
319 
320  builder.Translate(0, 100);
321  SkPath line_path2;
322  line_path2.moveTo(0, 0);
323  line_path2.lineTo(0, 0);
324  line_path2.lineTo(0, 0);
325  builder.DrawPath(line_path2, paint);
326 
327  builder.Restore();
328  }
329 
330  // Cubic.
331  builder.Translate(150, 0);
332  {
333  builder.Save();
334 
335  SkPath cubic_path;
336  cubic_path.moveTo({0, 0});
337  cubic_path.cubicTo(0, 0, 140.0, 100.0, 140, 20);
338  builder.DrawPath(cubic_path, paint);
339 
340  builder.Translate(0, 100);
341  SkPath cubic_path2;
342  cubic_path2.moveTo({0, 0});
343  cubic_path2.cubicTo(0, 0, 0, 0, 150, 150);
344  builder.DrawPath(cubic_path2, paint);
345 
346  builder.Translate(0, 100);
347  SkPath cubic_path3;
348  cubic_path3.moveTo({0, 0});
349  cubic_path3.cubicTo(0, 0, 0, 0, 0, 0);
350  builder.DrawPath(cubic_path3, paint);
351 
352  builder.Restore();
353  }
354 
355  // Quad.
356  builder.Translate(200, 0);
357  {
358  builder.Save();
359 
360  SkPath quad_path;
361  quad_path.moveTo(0, 0);
362  quad_path.moveTo(0, 0);
363  quad_path.quadTo({100, 40}, {50, 80});
364  builder.DrawPath(quad_path, paint);
365 
366  builder.Translate(0, 150);
367  SkPath quad_path2;
368  quad_path2.moveTo(0, 0);
369  quad_path2.moveTo(0, 0);
370  quad_path2.quadTo({0, 0}, {100, 100});
371  builder.DrawPath(quad_path2, paint);
372 
373  builder.Translate(0, 100);
374  SkPath quad_path3;
375  quad_path3.moveTo(0, 0);
376  quad_path3.quadTo({0, 0}, {0, 0});
377  builder.DrawPath(quad_path3, paint);
378 
379  builder.Restore();
380  }
381  return builder.Build();
382  };
383  ASSERT_TRUE(OpenPlaygroundHere(callback));
384 }

References stroke_width.

◆ TEST_P() [275/419]

impeller::testing::TEST_P ( DisplayListTest  ,
StrokedTextNotOffsetFromNormalText   
)

Definition at line 480 of file dl_unittests.cc.

480  {
481  flutter::DisplayListBuilder builder;
482  flutter::DlPaint paint;
483  auto const& text_blob = SkTextBlob::MakeFromString("00000", CreateTestFont());
484 
485  // https://api.flutter.dev/flutter/material/Colors/blue-constant.html.
486  auto const& mat_blue = flutter::DlColor(0xFF2196f3);
487 
488  // Draw a blue filled rectangle so the text is easier to see.
489  paint.setDrawStyle(flutter::DlDrawStyle::kFill);
490  paint.setColor(mat_blue);
491  builder.DrawRect(SkRect::MakeXYWH(0, 0, 500, 500), paint);
492 
493  // Draw stacked text, with stroked text on top.
494  paint.setDrawStyle(flutter::DlDrawStyle::kFill);
495  paint.setColor(flutter::DlColor::kWhite());
496  builder.DrawTextBlob(text_blob, 250, 250, paint);
497 
498  paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
499  paint.setColor(flutter::DlColor::kBlack());
500  builder.DrawTextBlob(text_blob, 250, 250, paint);
501 
502  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
503 }

◆ TEST_P() [276/419]

impeller::testing::TEST_P ( DisplayListTest  ,
TransparentShadowProducesCorrectColor   
)

Definition at line 949 of file dl_unittests.cc.

949  {
950  DlDispatcher dispatcher;
951  dispatcher.save();
952  dispatcher.scale(1.618, 1.618);
953  SkPath path = SkPath{}.addRect(SkRect::MakeXYWH(0, 0, 200, 100));
954  flutter::DlOpReceiver::CacheablePath cache(path);
955  dispatcher.drawShadow(cache, flutter::DlColor::kTransparent(), 15, false, 1);
956  dispatcher.restore();
957  auto picture = dispatcher.EndRecordingAsPicture();
958 
959  std::shared_ptr<SolidRRectBlurContents> rrect_blur;
960  picture.pass->IterateAllEntities([&rrect_blur](Entity& entity) {
961  if (ScalarNearlyEqual(entity.GetTransform().GetScale().x, 1.618f)) {
962  rrect_blur = std::static_pointer_cast<SolidRRectBlurContents>(
963  entity.GetContents());
964  return false;
965  }
966  return true;
967  });
968 
969  ASSERT_NE(rrect_blur, nullptr);
970  ASSERT_EQ(rrect_blur->GetColor().red, 0);
971  ASSERT_EQ(rrect_blur->GetColor().green, 0);
972  ASSERT_EQ(rrect_blur->GetColor().blue, 0);
973  ASSERT_EQ(rrect_blur->GetColor().alpha, 0);
974 }

References impeller::DlDispatcher::drawShadow(), impeller::DlDispatcher::EndRecordingAsPicture(), impeller::Matrix::GetScale(), impeller::Entity::GetTransform(), impeller::Picture::pass, impeller::DlDispatcher::restore(), impeller::DlDispatcher::save(), impeller::ScalarNearlyEqual(), impeller::DlDispatcher::scale(), and impeller::Vector3::x.

◆ TEST_P() [277/419]

impeller::testing::TEST_P ( DriverInfoVKTest  ,
CanQueryDriverInfo   
)

Definition at line 14 of file driver_info_vk_unittests.cc.

14  {
15  ASSERT_TRUE(GetContext());
16  const auto& driver_info =
17  SurfaceContextVK::Cast(*GetContext()).GetParent().GetDriverInfo();
18  ASSERT_NE(driver_info, nullptr);
19  // 1.1 is the base Impeller version. The driver can't be lower than that.
20  ASSERT_TRUE(driver_info->GetAPIVersion().IsAtLeast(Version{1, 1, 0}));
21  ASSERT_NE(driver_info->GetVendor(), VendorVK::kUnknown);
22  ASSERT_NE(driver_info->GetDeviceType(), DeviceTypeVK::kUnknown);
23  ASSERT_NE(driver_info->GetDriverName(), "");
24 }

References impeller::BackendCast< SurfaceContextVK, Context >::Cast(), impeller::ContextVK::GetDriverInfo(), impeller::SurfaceContextVK::GetParent(), and impeller::kUnknown.

◆ TEST_P() [278/419]

impeller::testing::TEST_P ( EntityPassTargetTest  ,
SwapWithMSAAImplicitResolve   
)

Definition at line 53 of file entity_pass_target_unittests.cc.

53  {
54  auto content_context = GetContentContext();
55  auto buffer = content_context->GetContext()->CreateCommandBuffer();
56  auto context = content_context->GetContext();
57  auto& allocator = *context->GetResourceAllocator();
58 
59  // Emulate implicit MSAA resolve by making color resolve and msaa texture the
60  // same.
61  RenderTarget render_target;
62  {
63  PixelFormat pixel_format =
64  context->GetCapabilities()->GetDefaultColorFormat();
65 
66  // Create MSAA color texture.
67 
68  TextureDescriptor color0_tex_desc;
69  color0_tex_desc.storage_mode = StorageMode::kDevicePrivate;
70  color0_tex_desc.type = TextureType::kTexture2DMultisample;
71  color0_tex_desc.sample_count = SampleCount::kCount4;
72  color0_tex_desc.format = pixel_format;
73  color0_tex_desc.size = ISize{100, 100};
74  color0_tex_desc.usage = TextureUsage::kRenderTarget;
75 
76  auto color0_msaa_tex = allocator.CreateTexture(color0_tex_desc);
77 
78  // Color attachment.
79 
80  ColorAttachment color0;
81  color0.load_action = LoadAction::kDontCare;
82  color0.store_action = StoreAction::kStoreAndMultisampleResolve;
83  color0.texture = color0_msaa_tex;
84  color0.resolve_texture = color0_msaa_tex;
85 
86  render_target.SetColorAttachment(color0, 0u);
87  render_target.SetStencilAttachment(std::nullopt);
88  }
89 
90  auto entity_pass_target = EntityPassTarget(render_target, false, true);
91 
92  auto color0 = entity_pass_target.GetRenderTarget()
93  .GetColorAttachments()
94  .find(0u)
95  ->second;
96  auto msaa_tex = color0.texture;
97  auto resolve_tex = color0.resolve_texture;
98 
99  ASSERT_EQ(msaa_tex, resolve_tex);
100 
101  entity_pass_target.Flip(
102  *content_context->GetContext()->GetResourceAllocator());
103 
104  color0 = entity_pass_target.GetRenderTarget()
105  .GetColorAttachments()
106  .find(0u)
107  ->second;
108 
109  ASSERT_NE(msaa_tex, color0.texture);
110  ASSERT_NE(resolve_tex, color0.resolve_texture);
111  ASSERT_EQ(color0.texture, color0.resolve_texture);
112 }

References impeller::TextureDescriptor::format, impeller::kCount4, impeller::kDevicePrivate, impeller::kDontCare, impeller::kRenderTarget, impeller::kStoreAndMultisampleResolve, impeller::kTexture2DMultisample, impeller::Attachment::load_action, impeller::Attachment::resolve_texture, impeller::TextureDescriptor::sample_count, impeller::RenderTarget::SetColorAttachment(), impeller::RenderTarget::SetStencilAttachment(), impeller::TextureDescriptor::size, impeller::TextureDescriptor::storage_mode, impeller::Attachment::store_action, impeller::Attachment::texture, impeller::TextureDescriptor::type, and impeller::TextureDescriptor::usage.

◆ TEST_P() [279/419]

impeller::testing::TEST_P ( EntityPassTargetTest  ,
SwapWithMSAATexture   
)

Definition at line 19 of file entity_pass_target_unittests.cc.

19  {
20  if (GetContentContext()
21  ->GetDeviceCapabilities()
22  .SupportsImplicitResolvingMSAA()) {
23  GTEST_SKIP() << "Implicit MSAA is used on this device.";
24  }
25  auto content_context = GetContentContext();
26  auto buffer = content_context->GetContext()->CreateCommandBuffer();
27  auto render_target =
28  GetContentContext()->GetRenderTargetCache()->CreateOffscreenMSAA(
29  *content_context->GetContext(), {100, 100},
30  /*mip_count=*/1);
31 
32  auto entity_pass_target = EntityPassTarget(render_target, false, false);
33 
34  auto color0 = entity_pass_target.GetRenderTarget()
35  .GetColorAttachments()
36  .find(0u)
37  ->second;
38  auto msaa_tex = color0.texture;
39  auto resolve_tex = color0.resolve_texture;
40 
41  entity_pass_target.Flip(
42  *content_context->GetContext()->GetResourceAllocator());
43 
44  color0 = entity_pass_target.GetRenderTarget()
45  .GetColorAttachments()
46  .find(0u)
47  ->second;
48 
49  ASSERT_EQ(msaa_tex, color0.texture);
50  ASSERT_NE(resolve_tex, color0.resolve_texture);
51 }

◆ TEST_P() [280/419]

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

Definition at line 2634 of file entity_unittests.cc.

2634  {
2635  if (GetContext()->GetCapabilities()->SupportsFramebufferFetch()) {
2636  GTEST_SKIP() << "Backends that support framebuffer fetch dont use coverage "
2637  "for advanced blends.";
2638  }
2639 
2640  auto contents = std::make_shared<SolidColorContents>();
2641  contents->SetGeometry(Geometry::MakeRect(Rect::MakeXYWH(100, 100, 100, 100)));
2642  contents->SetColor(Color::Red());
2643 
2644  Entity entity;
2645  entity.SetTransform(Matrix::MakeScale(Vector3(2, 2, 1)));
2646  entity.SetBlendMode(BlendMode::kColorBurn);
2647  entity.SetContents(contents);
2648 
2649  auto coverage = entity.GetCoverage();
2650  EXPECT_TRUE(coverage.has_value());
2651 
2652  auto pass = std::make_unique<EntityPass>();
2653  std::shared_ptr<RenderTargetCache> render_target_allocator =
2654  std::make_shared<RenderTargetCache>(GetContext()->GetResourceAllocator());
2655  auto stencil_config = RenderTarget::AttachmentConfig{
2656  .storage_mode = StorageMode::kDevicePrivate,
2657  .load_action = LoadAction::kClear,
2658  .store_action = StoreAction::kDontCare,
2659  .clear_color = Color::BlackTransparent()};
2660  auto rt = render_target_allocator->CreateOffscreen(
2661  *GetContext(), ISize::MakeWH(1000, 1000),
2662  /*mip_count=*/1, "Offscreen", RenderTarget::kDefaultColorAttachmentConfig,
2663  stencil_config);
2664  auto content_context = ContentContext(
2665  GetContext(), TypographerContextSkia::Make(), render_target_allocator);
2666  pass->AddEntity(std::move(entity));
2667 
2668  EXPECT_TRUE(pass->Render(content_context, rt));
2669 
2670  auto contains_size = [&render_target_allocator](ISize size) -> bool {
2671  return std::find_if(render_target_allocator->GetRenderTargetDataBegin(),
2672  render_target_allocator->GetRenderTargetDataEnd(),
2673  [&size](const auto& data) {
2674  return data.config.size == size;
2675  }) != render_target_allocator->GetRenderTargetDataEnd();
2676  };
2677 
2678  EXPECT_TRUE(contains_size(ISize(1000, 1000)))
2679  << "The root texture wasn't allocated";
2680  EXPECT_TRUE(contains_size(ISize(200, 200)))
2681  << "The ColorBurned texture wasn't allocated (100x100 scales up 2x)";
2682 }

References impeller::Color::BlackTransparent(), 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::TRect< Scalar >::MakeXYWH(), impeller::Color::Red(), impeller::Entity::SetBlendMode(), impeller::Entity::SetContents(), impeller::Entity::SetTransform(), and impeller::RenderTarget::AttachmentConfig::storage_mode.

◆ TEST_P() [281/419]

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

Definition at line 2030 of file entity_unittests.cc.

2030  {
2031  auto boston = CreateTextureForFixture("boston.jpg");
2032 
2033  {
2034  auto contents = std::make_shared<AtlasContents>();
2035  contents->SetBlendMode(BlendMode::kSourceOver);
2036  contents->SetTexture(boston);
2037  contents->SetColors({
2038  Color::Red(),
2039  Color::Red(),
2040  Color::Red(),
2041  });
2042  contents->SetTextureCoordinates({
2043  Rect::MakeLTRB(0, 0, 10, 10),
2044  Rect::MakeLTRB(0, 0, 10, 10),
2045  Rect::MakeLTRB(0, 0, 10, 10),
2046  });
2047  contents->SetTransforms({
2048  Matrix::MakeTranslation(Vector2(0, 0)),
2049  Matrix::MakeTranslation(Vector2(100, 100)),
2050  Matrix::MakeTranslation(Vector2(200, 200)),
2051  });
2052 
2053  // Since all colors and sample rects are the same, there should
2054  // only be a single entry in the sub atlas.
2055  auto subatlas = contents->GenerateSubAtlas();
2056  ASSERT_EQ(subatlas->sub_texture_coords.size(), 1u);
2057  }
2058 
2059  {
2060  auto contents = std::make_shared<AtlasContents>();
2061  contents->SetBlendMode(BlendMode::kSourceOver);
2062  contents->SetTexture(boston);
2063  contents->SetColors({
2064  Color::Red(),
2065  Color::Green(),
2066  Color::Blue(),
2067  });
2068  contents->SetTextureCoordinates({
2069  Rect::MakeLTRB(0, 0, 10, 10),
2070  Rect::MakeLTRB(0, 0, 10, 10),
2071  Rect::MakeLTRB(0, 0, 10, 10),
2072  });
2073  contents->SetTransforms({
2074  Matrix::MakeTranslation(Vector2(0, 0)),
2075  Matrix::MakeTranslation(Vector2(100, 100)),
2076  Matrix::MakeTranslation(Vector2(200, 200)),
2077  });
2078 
2079  // Since all colors are different, there are three entires.
2080  auto subatlas = contents->GenerateSubAtlas();
2081  ASSERT_EQ(subatlas->sub_texture_coords.size(), 3u);
2082 
2083  // The translations are kept but the sample rects point into
2084  // different parts of the sub atlas.
2085  ASSERT_EQ(subatlas->result_texture_coords[0], Rect::MakeXYWH(0, 0, 10, 10));
2086  ASSERT_EQ(subatlas->result_texture_coords[1],
2087  Rect::MakeXYWH(11, 0, 10, 10));
2088  ASSERT_EQ(subatlas->result_texture_coords[2],
2089  Rect::MakeXYWH(22, 0, 10, 10));
2090  }
2091 }

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

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

Definition at line 989 of file entity_unittests.cc.

989  {
990  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
991  static float scale = 20;
992 
993  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
994  ImGui::SliderFloat("Scale", &scale, 1, 100);
995  ImGui::End();
996 
997  Entity entity;
998  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
999  auto path = PathBuilder{}
1000  .MoveTo({97.325, 34.818})
1001  .CubicCurveTo({98.50862885295136, 34.81812293973836},
1002  {99.46822048142015, 33.85863261475589},
1003  {99.46822048142015, 32.67499810206613})
1004  .CubicCurveTo({99.46822048142015, 31.491363589376355},
1005  {98.50862885295136, 30.53187326439389},
1006  {97.32499434685802, 30.531998226542708})
1007  .CubicCurveTo({96.14153655073771, 30.532123170035373},
1008  {95.18222070648729, 31.491540299350355},
1009  {95.18222070648729, 32.67499810206613})
1010  .CubicCurveTo({95.18222070648729, 33.85845590478189},
1011  {96.14153655073771, 34.81787303409686},
1012  {97.32499434685802, 34.81799797758954})
1013  .Close()
1014  .TakePath();
1015  entity.SetTransform(
1016  Matrix::MakeScale({scale, scale, 1.0}).Translate({-90, -20, 0}));
1017  entity.SetContents(SolidColorContents::Make(path, Color::Red()));
1018  return entity.Render(context, pass);
1019  };
1020  ASSERT_TRUE(OpenPlaygroundHere(callback));
1021 }

References impeller::Close(), impeller::SolidColorContents::Make(), impeller::Matrix::MakeScale(), impeller::PathBuilder::MoveTo(), impeller::Color::Red(), impeller::Entity::Render(), scale, impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [283/419]

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

Definition at line 861 of file entity_unittests.cc.

861  {
862  std::vector<const char*> blend_mode_names;
863  std::vector<BlendMode> blend_mode_values;
864  {
865  // Force an exhausiveness check with a switch. When adding blend modes,
866  // update this switch with a new name/value to make it selectable in the
867  // test GUI.
868 
869  const BlendMode b{};
870  static_assert(b == BlendMode::kClear); // Ensure the first item in
871  // the switch is the first
872  // item in the enum.
873  static_assert(Entity::kLastPipelineBlendMode == BlendMode::kModulate);
874  switch (b) {
875  case BlendMode::kClear:
876  blend_mode_names.push_back("Clear");
877  blend_mode_values.push_back(BlendMode::kClear);
878  case BlendMode::kSource:
879  blend_mode_names.push_back("Source");
880  blend_mode_values.push_back(BlendMode::kSource);
881  case BlendMode::kDestination:
882  blend_mode_names.push_back("Destination");
883  blend_mode_values.push_back(BlendMode::kDestination);
884  case BlendMode::kSourceOver:
885  blend_mode_names.push_back("SourceOver");
886  blend_mode_values.push_back(BlendMode::kSourceOver);
887  case BlendMode::kDestinationOver:
888  blend_mode_names.push_back("DestinationOver");
889  blend_mode_values.push_back(BlendMode::kDestinationOver);
890  case BlendMode::kSourceIn:
891  blend_mode_names.push_back("SourceIn");
892  blend_mode_values.push_back(BlendMode::kSourceIn);
893  case BlendMode::kDestinationIn:
894  blend_mode_names.push_back("DestinationIn");
895  blend_mode_values.push_back(BlendMode::kDestinationIn);
896  case BlendMode::kSourceOut:
897  blend_mode_names.push_back("SourceOut");
898  blend_mode_values.push_back(BlendMode::kSourceOut);
899  case BlendMode::kDestinationOut:
900  blend_mode_names.push_back("DestinationOut");
901  blend_mode_values.push_back(BlendMode::kDestinationOut);
902  case BlendMode::kSourceATop:
903  blend_mode_names.push_back("SourceATop");
904  blend_mode_values.push_back(BlendMode::kSourceATop);
905  case BlendMode::kDestinationATop:
906  blend_mode_names.push_back("DestinationATop");
907  blend_mode_values.push_back(BlendMode::kDestinationATop);
908  case BlendMode::kXor:
909  blend_mode_names.push_back("Xor");
910  blend_mode_values.push_back(BlendMode::kXor);
911  case BlendMode::kPlus:
912  blend_mode_names.push_back("Plus");
913  blend_mode_values.push_back(BlendMode::kPlus);
914  case BlendMode::kModulate:
915  blend_mode_names.push_back("Modulate");
916  blend_mode_values.push_back(BlendMode::kModulate);
917  };
918  }
919 
920  auto callback = [&](ContentContext& context, RenderPass& pass) {
921  auto world_matrix = Matrix::MakeScale(GetContentScale());
922  auto draw_rect = [&context, &pass, &world_matrix](
923  Rect rect, Color color, BlendMode blend_mode) -> bool {
924  using VS = SolidFillPipeline::VertexShader;
925 
926  VertexBufferBuilder<VS::PerVertexData> vtx_builder;
927  {
928  auto r = rect.GetLTRB();
929  vtx_builder.AddVertices({
930  {Point(r[0], r[1])},
931  {Point(r[2], r[1])},
932  {Point(r[2], r[3])},
933  {Point(r[0], r[1])},
934  {Point(r[2], r[3])},
935  {Point(r[0], r[3])},
936  });
937  }
938 
939  pass.SetCommandLabel("Blended Rectangle");
940  auto options = OptionsFromPass(pass);
941  options.blend_mode = blend_mode;
942  options.primitive_type = PrimitiveType::kTriangle;
943  pass.SetPipeline(context.GetSolidFillPipeline(options));
944  pass.SetVertexBuffer(
945  vtx_builder.CreateVertexBuffer(context.GetTransientsBuffer()));
946 
947  VS::FrameInfo frame_info;
948  frame_info.mvp = pass.GetOrthographicTransform() * world_matrix;
949  frame_info.color = color.Premultiply();
950  VS::BindFrameInfo(
951  pass, context.GetTransientsBuffer().EmplaceUniform(frame_info));
952 
953  return pass.Draw().ok();
954  };
955 
956  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
957  static Color color1(1, 0, 0, 0.5), color2(0, 1, 0, 0.5);
958  ImGui::ColorEdit4("Color 1", reinterpret_cast<float*>(&color1));
959  ImGui::ColorEdit4("Color 2", reinterpret_cast<float*>(&color2));
960  static int current_blend_index = 3;
961  ImGui::ListBox("Blending mode", &current_blend_index,
962  blend_mode_names.data(), blend_mode_names.size());
963  ImGui::End();
964 
965  BlendMode selected_mode = blend_mode_values[current_blend_index];
966 
967  Point a, b, c, d;
968  static PlaygroundPoint point_a(Point(400, 100), 20, Color::White());
969  static PlaygroundPoint point_b(Point(200, 300), 20, Color::White());
970  std::tie(a, b) = DrawPlaygroundLine(point_a, point_b);
971  static PlaygroundPoint point_c(Point(470, 190), 20, Color::White());
972  static PlaygroundPoint point_d(Point(270, 390), 20, Color::White());
973  std::tie(c, d) = DrawPlaygroundLine(point_c, point_d);
974 
975  bool result = true;
976  result = result &&
977  draw_rect(Rect::MakeXYWH(0, 0, pass.GetRenderTargetSize().width,
978  pass.GetRenderTargetSize().height),
979  Color(), BlendMode::kClear);
980  result = result && draw_rect(Rect::MakeLTRB(a.x, a.y, b.x, b.y), color1,
981  BlendMode::kSourceOver);
982  result = result && draw_rect(Rect::MakeLTRB(c.x, c.y, d.x, d.y), color2,
983  selected_mode);
984  return result;
985  };
986  ASSERT_TRUE(OpenPlaygroundHere(callback));
987 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::saturated::b, impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::DrawPlaygroundLine(), impeller::HostBuffer::EmplaceUniform(), impeller::ContentContext::GetSolidFillPipeline(), impeller::ContentContext::GetTransientsBuffer(), 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::MakeScale(), impeller::TRect< Scalar >::MakeXYWH(), impeller::OptionsFromPass(), impeller::Color::White(), impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ TEST_P() [284/419]

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

Definition at line 1390 of file entity_unittests.cc.

1390  {
1391  auto fill = std::make_shared<SolidColorContents>();
1392  fill->SetGeometry(Geometry::MakeFillPath(
1393  PathBuilder{}.AddRect(Rect::MakeXYWH(0, 0, 300, 400)).TakePath()));
1394  fill->SetColor(Color::CornflowerBlue());
1395  auto border_mask_blur = FilterContents::MakeBorderMaskBlur(
1396  FilterInput::Make(fill), Radius{3}, Radius{4});
1397 
1398  {
1399  Entity e;
1400  e.SetTransform(Matrix());
1401  auto actual = border_mask_blur->GetCoverage(e);
1402  auto expected = Rect::MakeXYWH(-3, -4, 306, 408);
1403  ASSERT_TRUE(actual.has_value());
1404  ASSERT_RECT_NEAR(actual.value(), expected);
1405  }
1406 
1407  {
1408  Entity e;
1409  e.SetTransform(Matrix::MakeRotationZ(Radians{kPi / 4}));
1410  auto actual = border_mask_blur->GetCoverage(e);
1411  auto expected = Rect::MakeXYWH(-287.792, -4.94975, 504.874, 504.874);
1412  ASSERT_TRUE(actual.has_value());
1413  ASSERT_RECT_NEAR(actual.value(), expected);
1414  }
1415 }

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::SetTransform().

◆ TEST_P() [285/419]

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

Definition at line 2816 of file entity_unittests.cc.

2816  {
2817  PathBuilder builder = {};
2818  builder.AddRect(Rect::MakeLTRB(0, 0, 0, 0));
2819  Path path = builder.TakePath();
2820 
2821  EXPECT_TRUE(path.GetBoundingBox()->IsEmpty());
2822 
2823  auto geom = Geometry::MakeFillPath(path);
2824 
2825  Entity entity;
2826  RenderTarget target =
2827  GetContentContext()->GetRenderTargetCache()->CreateOffscreen(
2828  *GetContext(), {1, 1}, 1u);
2829  testing::MockRenderPass render_pass(GetContext(), target);
2830  auto position_result =
2831  geom->GetPositionBuffer(*GetContentContext(), entity, render_pass);
2832 
2833  auto uv_result =
2834  geom->GetPositionUVBuffer(Rect::MakeLTRB(0, 0, 100, 100), Matrix(),
2835  *GetContentContext(), entity, render_pass);
2836 
2837  EXPECT_EQ(position_result.vertex_buffer.vertex_count, 0u);
2838  EXPECT_EQ(uv_result.vertex_buffer.vertex_count, 0u);
2839 
2840  EXPECT_EQ(geom->GetResultMode(), GeometryResult::Mode::kNormal);
2841 }

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

◆ TEST_P() [286/419]

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

Definition at line 70 of file entity_unittests.cc.

70  {
71  Entity entity;
72  ASSERT_TRUE(entity.GetTransform().IsIdentity());
73 }

References impeller::Entity::GetTransform(), and impeller::Matrix::IsIdentity().

◆ TEST_P() [287/419]

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

Definition at line 545 of file entity_unittests.cc.

545  {
546  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
547  const char* input_axis[] = {"X", "Y", "Z"};
548  static int rotation_axis_index = 0;
549  static float rotation = 0;
550  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
551  ImGui::SliderFloat("Rotation", &rotation, -kPi, kPi);
552  ImGui::Combo("Rotation Axis", &rotation_axis_index, input_axis,
553  sizeof(input_axis) / sizeof(char*));
554  Matrix rotation_matrix;
555  switch (rotation_axis_index) {
556  case 0:
557  rotation_matrix = Matrix::MakeRotationX(Radians(rotation));
558  break;
559  case 1:
560  rotation_matrix = Matrix::MakeRotationY(Radians(rotation));
561  break;
562  case 2:
563  rotation_matrix = Matrix::MakeRotationZ(Radians(rotation));
564  break;
565  default:
566  rotation_matrix = Matrix{};
567  break;
568  }
569 
570  if (ImGui::Button("Reset")) {
571  rotation = 0;
572  }
573  ImGui::End();
574  Matrix current_transform =
575  Matrix::MakeScale(GetContentScale())
576  .MakeTranslation(
577  Vector3(Point(pass.GetRenderTargetSize().width / 2.0,
578  pass.GetRenderTargetSize().height / 2.0)));
579  Matrix result_transform = current_transform * rotation_matrix;
580  Path path =
581  PathBuilder{}.AddRect(Rect::MakeXYWH(-300, -400, 600, 800)).TakePath();
582 
583  Entity entity;
584  entity.SetTransform(result_transform);
585  entity.SetContents(SolidColorContents::Make(path, Color::Red()));
586  return entity.Render(context, pass);
587  };
588  ASSERT_TRUE(OpenPlaygroundHere(callback));
589 }

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::SetTransform(), and impeller::PathBuilder::TakePath().

◆ TEST_P() [288/419]

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

Definition at line 264 of file entity_unittests.cc.

264  {
265  auto contents = std::make_shared<SolidColorContents>();
266  contents->SetGeometry(Geometry::MakeRect(Rect::MakeXYWH(100, 100, 100, 100)));
267  contents->SetColor(Color::Red());
268 
269  Entity entity;
270  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
271  entity.SetContents(contents);
272 
273  ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
274 }

References impeller::Geometry::MakeRect(), impeller::Matrix::MakeScale(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Color::Red(), impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [289/419]

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

Definition at line 276 of file entity_unittests.cc.

276  {
277  auto contents = std::make_shared<SolidColorContents>();
278  auto path = PathBuilder{}
279  .SetConvexity(Convexity::kConvex)
280  .AddRoundedRect(Rect::MakeXYWH(100, 100, 100, 100), 10.0)
281  .TakePath();
282  contents->SetGeometry(Geometry::MakeFillPath(path));
283  contents->SetColor(Color::Red());
284 
285  Entity entity;
286  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
287  entity.SetContents(contents);
288 
289  ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
290 }

References impeller::PathBuilder::AddRoundedRect(), impeller::kConvex, impeller::Geometry::MakeFillPath(), impeller::Matrix::MakeScale(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Color::Red(), impeller::Entity::SetContents(), impeller::PathBuilder::SetConvexity(), impeller::Entity::SetTransform(), and impeller::PathBuilder::TakePath().

◆ TEST_P() [290/419]

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

Definition at line 2843 of file entity_unittests.cc.

2843  {
2844  PathBuilder builder = {};
2845  builder.AddRect(Rect::MakeLTRB(0, 0, 0, 0));
2846  Path path = builder.TakePath();
2847 
2848  EXPECT_TRUE(path.GetBoundingBox()->IsEmpty());
2849 
2850  auto contents = std::make_shared<SolidColorContents>();
2851  contents->SetGeometry(Geometry::MakeFillPath(path));
2852  contents->SetColor(Color::Red());
2853 
2854  Entity entity;
2855  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
2856  entity.SetContents(contents);
2857 
2858  ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
2859 }

References impeller::PathBuilder::AddRect(), impeller::Path::GetBoundingBox(), impeller::Geometry::MakeFillPath(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeScale(), impeller::Color::Red(), impeller::Entity::SetContents(), impeller::Entity::SetTransform(), and impeller::PathBuilder::TakePath().

◆ TEST_P() [291/419]

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

Definition at line 1726 of file entity_unittests.cc.

1726  {
1727  // Intersection: No stencil coverage, no geometry.
1728  {
1729  auto clip = std::make_shared<ClipContents>();
1730  clip->SetClipOperation(Entity::ClipOperation::kIntersect);
1731  auto result = clip->GetClipCoverage(Entity{}, Rect{});
1732 
1733  ASSERT_FALSE(result.coverage.has_value());
1734  }
1735 
1736  // Intersection: No stencil coverage, with geometry.
1737  {
1738  auto clip = std::make_shared<ClipContents>();
1739  clip->SetClipOperation(Entity::ClipOperation::kIntersect);
1740  clip->SetGeometry(Geometry::MakeFillPath(
1741  PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 100, 100)).TakePath()));
1742  auto result = clip->GetClipCoverage(Entity{}, Rect{});
1743 
1744  ASSERT_FALSE(result.coverage.has_value());
1745  }
1746 
1747  // Intersection: With stencil coverage, no geometry.
1748  {
1749  auto clip = std::make_shared<ClipContents>();
1750  clip->SetClipOperation(Entity::ClipOperation::kIntersect);
1751  auto result =
1752  clip->GetClipCoverage(Entity{}, Rect::MakeLTRB(0, 0, 100, 100));
1753 
1754  ASSERT_FALSE(result.coverage.has_value());
1755  }
1756 
1757  // Intersection: With stencil coverage, with geometry.
1758  {
1759  auto clip = std::make_shared<ClipContents>();
1760  clip->SetClipOperation(Entity::ClipOperation::kIntersect);
1761  clip->SetGeometry(Geometry::MakeFillPath(
1762  PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 50, 50)).TakePath()));
1763  auto result =
1764  clip->GetClipCoverage(Entity{}, Rect::MakeLTRB(0, 0, 100, 100));
1765 
1766  ASSERT_TRUE(result.coverage.has_value());
1767  ASSERT_RECT_NEAR(result.coverage.value(), Rect::MakeLTRB(0, 0, 50, 50));
1768  ASSERT_EQ(result.type, Contents::ClipCoverage::Type::kAppend);
1769  }
1770 
1771  // Difference: With stencil coverage, with geometry.
1772  {
1773  auto clip = std::make_shared<ClipContents>();
1774  clip->SetClipOperation(Entity::ClipOperation::kDifference);
1775  clip->SetGeometry(Geometry::MakeFillPath(
1776  PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 50, 50)).TakePath()));
1777  auto result =
1778  clip->GetClipCoverage(Entity{}, Rect::MakeLTRB(0, 0, 100, 100));
1779 
1780  ASSERT_TRUE(result.coverage.has_value());
1781  ASSERT_RECT_NEAR(result.coverage.value(), Rect::MakeLTRB(0, 0, 100, 100));
1782  ASSERT_EQ(result.type, Contents::ClipCoverage::Type::kAppend);
1783  }
1784 }

References impeller::PathBuilder::AddRect(), ASSERT_RECT_NEAR, impeller::Contents::ClipCoverage::kAppend, impeller::Entity::kDifference, impeller::Entity::kIntersect, impeller::Geometry::MakeFillPath(), and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST_P() [292/419]

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

Definition at line 1702 of file entity_unittests.cc.

1702  {
1703  // For clip ops, `ShouldRender` should always return true.
1704 
1705  // Clip.
1706  {
1707  auto clip = std::make_shared<ClipContents>();
1708  ASSERT_TRUE(clip->ShouldRender(Entity{}, Rect::MakeSize(Size{100, 100})));
1709  clip->SetGeometry(Geometry::MakeFillPath(
1710  PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 100, 100)).TakePath()));
1711  ASSERT_TRUE(clip->ShouldRender(Entity{}, Rect::MakeSize(Size{100, 100})));
1712  ASSERT_TRUE(
1713  clip->ShouldRender(Entity{}, Rect::MakeLTRB(-100, -100, -50, -50)));
1714  }
1715 
1716  // Clip restore.
1717  {
1718  auto restore = std::make_shared<ClipRestoreContents>();
1719  ASSERT_TRUE(
1720  restore->ShouldRender(Entity{}, Rect::MakeSize(Size{100, 100})));
1721  ASSERT_TRUE(
1722  restore->ShouldRender(Entity{}, Rect::MakeLTRB(-100, -100, -50, -50)));
1723  }
1724 }

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

◆ TEST_P() [293/419]

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

Definition at line 2607 of file entity_unittests.cc.

2607  {
2608  Entity entity;
2609  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
2610  auto src_contents = std::make_shared<SolidColorContents>();
2611  src_contents->SetGeometry(
2612  Geometry::MakeRect(Rect::MakeLTRB(-300, -500, 30000, 50000)));
2613  src_contents->SetColor(Color::Red());
2614 
2615  auto dst_contents = std::make_shared<SolidColorContents>();
2616  dst_contents->SetGeometry(
2617  Geometry::MakeRect(Rect::MakeLTRB(300, 500, 20000, 30000)));
2618  dst_contents->SetColor(Color::Blue());
2619 
2620  auto contents = ColorFilterContents::MakeBlend(
2621  BlendMode::kSourceOver, {FilterInput::Make(dst_contents, false),
2622  FilterInput::Make(src_contents, false)});
2623  entity.SetContents(std::move(contents));
2624  ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
2625 }

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::SetTransform().

◆ TEST_P() [294/419]

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

Definition at line 2426 of file entity_unittests.cc.

2426  {
2427  auto image = CreateTextureForFixture("boston.jpg");
2428  auto filter = ColorFilterContents::MakeBlend(
2429  BlendMode::kColorBurn, FilterInput::Make({image}), Color::Red());
2430 
2431  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
2432  Entity entity;
2433  entity.SetTransform(Matrix::MakeScale(GetContentScale()) *
2434  Matrix::MakeTranslation({500, 300}) *
2435  Matrix::MakeScale(Vector2{0.5, 0.5}));
2436  entity.SetContents(filter);
2437  return entity.Render(context, pass);
2438  };
2439  ASSERT_TRUE(OpenPlaygroundHere(callback));
2440 }

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::SetTransform().

◆ TEST_P() [295/419]

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

Definition at line 2442 of file entity_unittests.cc.

2442  {
2443  auto image = CreateTextureForFixture("boston.jpg");
2444  auto filter = ColorFilterContents::MakeBlend(
2445  BlendMode::kClear, FilterInput::Make({image}), Color::Red());
2446 
2447  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
2448  Entity entity;
2449  entity.SetTransform(Matrix::MakeScale(GetContentScale()) *
2450  Matrix::MakeTranslation({500, 300}) *
2451  Matrix::MakeScale(Vector2{0.5, 0.5}));
2452  entity.SetContents(filter);
2453  return entity.Render(context, pass);
2454  };
2455  ASSERT_TRUE(OpenPlaygroundHere(callback));
2456 }

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::SetTransform().

◆ TEST_P() [296/419]

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

Definition at line 2474 of file entity_unittests.cc.

2474  {
2475  auto image = CreateTextureForFixture("boston.jpg");
2476  auto filter = ColorFilterContents::MakeBlend(
2477  BlendMode::kDestination, FilterInput::Make({image}), Color::Red());
2478 
2479  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
2480  Entity entity;
2481  entity.SetTransform(Matrix::MakeScale(GetContentScale()) *
2482  Matrix::MakeTranslation({500, 300}) *
2483  Matrix::MakeScale(Vector2{0.5, 0.5}));
2484  entity.SetContents(filter);
2485  return entity.Render(context, pass);
2486  };
2487  ASSERT_TRUE(OpenPlaygroundHere(callback));
2488 }

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::SetTransform().

◆ TEST_P() [297/419]

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

Definition at line 2458 of file entity_unittests.cc.

2458  {
2459  auto image = CreateTextureForFixture("boston.jpg");
2460  auto filter = ColorFilterContents::MakeBlend(
2461  BlendMode::kSource, FilterInput::Make({image}), Color::Red());
2462 
2463  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
2464  Entity entity;
2465  entity.SetTransform(Matrix::MakeScale(GetContentScale()) *
2466  Matrix::MakeTranslation({500, 300}) *
2467  Matrix::MakeScale(Vector2{0.5, 0.5}));
2468  entity.SetContents(filter);
2469  return entity.Render(context, pass);
2470  };
2471  ASSERT_TRUE(OpenPlaygroundHere(callback));
2472 }

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::SetTransform().

◆ TEST_P() [298/419]

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

Definition at line 2490 of file entity_unittests.cc.

2490  {
2491  auto image = CreateTextureForFixture("boston.jpg");
2492  auto filter = ColorFilterContents::MakeBlend(
2493  BlendMode::kSourceIn, FilterInput::Make({image}), Color::Red());
2494 
2495  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
2496  Entity entity;
2497  entity.SetTransform(Matrix::MakeScale(GetContentScale()) *
2498  Matrix::MakeTranslation({500, 300}) *
2499  Matrix::MakeScale(Vector2{0.5, 0.5}));
2500  entity.SetContents(filter);
2501  return entity.Render(context, pass);
2502  };
2503  ASSERT_TRUE(OpenPlaygroundHere(callback));
2504 }

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::SetTransform().

◆ TEST_P() [299/419]

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

Definition at line 1839 of file entity_unittests.cc.

1839  {
1840  // Set up a simple color background.
1841  auto fill = std::make_shared<SolidColorContents>();
1842  fill->SetGeometry(Geometry::MakeFillPath(
1843  PathBuilder{}.AddRect(Rect::MakeXYWH(0, 0, 300, 400)).TakePath()));
1844  fill->SetColor(Color::Coral());
1845 
1846  // Set the color matrix filter.
1847  ColorMatrix matrix = {
1848  1, 1, 1, 1, 1, //
1849  1, 1, 1, 1, 1, //
1850  1, 1, 1, 1, 1, //
1851  1, 1, 1, 1, 1, //
1852  };
1853 
1854  auto filter =
1855  ColorFilterContents::MakeColorMatrix(FilterInput::Make(fill), matrix);
1856 
1857  Entity e;
1858  e.SetTransform(Matrix());
1859 
1860  // Confirm that the actual filter coverage matches the expected coverage.
1861  auto actual = filter->GetCoverage(e);
1862  auto expected = Rect::MakeXYWH(0, 0, 300, 400);
1863 
1864  ASSERT_TRUE(actual.has_value());
1865  ASSERT_RECT_NEAR(actual.value(), expected);
1866 }

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::SetTransform().

◆ TEST_P() [300/419]

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

Definition at line 1868 of file entity_unittests.cc.

1868  {
1869  auto bay_bridge = CreateTextureForFixture("bay_bridge.jpg");
1870  ASSERT_TRUE(bay_bridge);
1871 
1872  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1873  // UI state.
1874  static ColorMatrix color_matrix = {
1875  1, 0, 0, 0, 0, //
1876  0, 3, 0, 0, 0, //
1877  0, 0, 1, 0, 0, //
1878  0, 0, 0, 1, 0, //
1879  };
1880  static float offset[2] = {500, 400};
1881  static float rotation = 0;
1882  static float scale[2] = {0.65, 0.65};
1883  static float skew[2] = {0, 0};
1884 
1885  // Define the ImGui
1886  ImGui::Begin("Color Matrix", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1887  {
1888  std::string label = "##1";
1889  for (int i = 0; i < 20; i += 5) {
1890  ImGui::InputScalarN(label.c_str(), ImGuiDataType_Float,
1891  &(color_matrix.array[i]), 5, nullptr, nullptr,
1892  "%.2f", 0);
1893  label[2]++;
1894  }
1895 
1896  ImGui::SliderFloat2("Translation", &offset[0], 0,
1897  pass.GetRenderTargetSize().width);
1898  ImGui::SliderFloat("Rotation", &rotation, 0, kPi * 2);
1899  ImGui::SliderFloat2("Scale", &scale[0], 0, 3);
1900  ImGui::SliderFloat2("Skew", &skew[0], -3, 3);
1901  }
1902  ImGui::End();
1903 
1904  // Set the color matrix filter.
1905  auto filter = ColorFilterContents::MakeColorMatrix(
1906  FilterInput::Make(bay_bridge), color_matrix);
1907 
1908  // Define the entity with the color matrix filter.
1909  Entity entity;
1910  entity.SetTransform(
1911  Matrix::MakeScale(GetContentScale()) *
1912  Matrix::MakeTranslation(Vector3(offset[0], offset[1])) *
1913  Matrix::MakeRotationZ(Radians(rotation)) *
1914  Matrix::MakeScale(Vector2(scale[0], scale[1])) *
1915  Matrix::MakeSkew(skew[0], skew[1]) *
1916  Matrix::MakeTranslation(-Point(bay_bridge->GetSize()) / 2));
1917  entity.SetContents(filter);
1918  entity.Render(context, pass);
1919 
1920  return true;
1921  };
1922 
1923  ASSERT_TRUE(OpenPlaygroundHere(callback));
1924 }

References impeller::ColorMatrix::array, impeller::kPi, impeller::FilterInput::Make(), impeller::ColorFilterContents::MakeColorMatrix(), impeller::Matrix::MakeRotationZ(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeSkew(), impeller::Matrix::MakeTranslation(), offset, impeller::Entity::Render(), scale, impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [301/419]

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

Definition at line 2530 of file entity_unittests.cc.

2530  {
2531  ConicalGradientContents contents;
2532  contents.SetColors({Color::CornflowerBlue()});
2533  ASSERT_FALSE(contents.IsOpaque());
2534  contents.SetColors({Color::CornflowerBlue().WithAlpha(0.5)});
2535  ASSERT_FALSE(contents.IsOpaque());
2536 }

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

◆ TEST_P() [302/419]

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

Definition at line 2722 of file entity_unittests.cc.

2722  {
2723  ContentContextOptions opts;
2724  auto hash_a = ContentContextOptions::Hash{}(opts);
2725 
2726  opts.blend_mode = BlendMode::kColorBurn;
2727  auto hash_b = ContentContextOptions::Hash{}(opts);
2728 
2729  opts.has_depth_stencil_attachments = false;
2730  auto hash_c = ContentContextOptions::Hash{}(opts);
2731 
2732  opts.primitive_type = PrimitiveType::kPoint;
2733  auto hash_d = ContentContextOptions::Hash{}(opts);
2734 
2735  EXPECT_NE(hash_a, hash_b);
2736  EXPECT_NE(hash_b, hash_c);
2737  EXPECT_NE(hash_c, hash_d);
2738 }

References impeller::ContentContextOptions::blend_mode, impeller::ContentContextOptions::has_depth_stencil_attachments, impeller::kColorBurn, impeller::kPoint, and impeller::ContentContextOptions::primitive_type.

◆ TEST_P() [303/419]

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

Definition at line 1331 of file entity_unittests.cc.

1331  {
1332  Entity entity;
1333  entity.SetContents(std::make_shared<SolidColorContents>());
1334  ASSERT_FALSE(entity.GetCoverage().has_value());
1335 }

References impeller::Entity::GetCoverage(), and impeller::Entity::SetContents().

◆ TEST_P() [304/419]

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

Definition at line 2506 of file entity_unittests.cc.

2506  {
2507  auto arrow_head = PathBuilder{}
2508  .MoveTo({50, 120})
2509  .LineTo({120, 190})
2510  .LineTo({190, 120})
2511  .TakePath();
2512  auto geometry = Geometry::MakeStrokePath(arrow_head, 15.0, 4.0, Cap::kRound,
2513  Join::kRound);
2514 
2515  auto transform = Matrix::MakeTranslation({300, 300}) *
2516  Matrix::MakeRotationZ(Radians(kPiOver2));
2517  EXPECT_LT(transform.e[0][0], 0.f);
2518  auto coverage = geometry->GetCoverage(transform);
2519  ASSERT_RECT_NEAR(coverage.value(), Rect::MakeXYWH(102.5, 342.5, 85, 155));
2520 }

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

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

Definition at line 591 of file entity_unittests.cc.

591  {
592  // Compare with https://fiddle.skia.org/c/7a05a3e186c65a8dfb732f68020aae06
593  Path path =
594  PathBuilder{}
595  .MoveTo({359.934, 96.6335})
596  .CubicCurveTo({358.189, 96.7055}, {356.436, 96.7908},
597  {354.673, 96.8895})
598  .CubicCurveTo({354.571, 96.8953}, {354.469, 96.9016},
599  {354.367, 96.9075})
600  .CubicCurveTo({352.672, 97.0038}, {350.969, 97.113},
601  {349.259, 97.2355})
602  .CubicCurveTo({349.048, 97.2506}, {348.836, 97.2678},
603  {348.625, 97.2834})
604  .CubicCurveTo({347.019, 97.4014}, {345.407, 97.5299},
605  {343.789, 97.6722})
606  .CubicCurveTo({343.428, 97.704}, {343.065, 97.7402},
607  {342.703, 97.7734})
608  .CubicCurveTo({341.221, 97.9086}, {339.736, 98.0505},
609  {338.246, 98.207})
610  .CubicCurveTo({337.702, 98.2642}, {337.156, 98.3292},
611  {336.612, 98.3894})
612  .CubicCurveTo({335.284, 98.5356}, {333.956, 98.6837},
613  {332.623, 98.8476})
614  .CubicCurveTo({332.495, 98.8635}, {332.366, 98.8818},
615  {332.237, 98.8982})
616  .LineTo({332.237, 102.601})
617  .LineTo({321.778, 102.601})
618  .LineTo({321.778, 100.382})
619  .CubicCurveTo({321.572, 100.413}, {321.367, 100.442},
620  {321.161, 100.476})
621  .CubicCurveTo({319.22, 100.79}, {317.277, 101.123},
622  {315.332, 101.479})
623  .CubicCurveTo({315.322, 101.481}, {315.311, 101.482},
624  {315.301, 101.484})
625  .LineTo({310.017, 105.94})
626  .LineTo({309.779, 105.427})
627  .LineTo({314.403, 101.651})
628  .CubicCurveTo({314.391, 101.653}, {314.379, 101.656},
629  {314.368, 101.658})
630  .CubicCurveTo({312.528, 102.001}, {310.687, 102.366},
631  {308.846, 102.748})
632  .CubicCurveTo({307.85, 102.955}, {306.855, 103.182}, {305.859, 103.4})
633  .CubicCurveTo({305.048, 103.579}, {304.236, 103.75},
634  {303.425, 103.936})
635  .LineTo({299.105, 107.578})
636  .LineTo({298.867, 107.065})
637  .LineTo({302.394, 104.185})
638  .LineTo({302.412, 104.171})
639  .CubicCurveTo({301.388, 104.409}, {300.366, 104.67},
640  {299.344, 104.921})
641  .CubicCurveTo({298.618, 105.1}, {297.89, 105.269}, {297.165, 105.455})
642  .CubicCurveTo({295.262, 105.94}, {293.36, 106.445},
643  {291.462, 106.979})
644  .CubicCurveTo({291.132, 107.072}, {290.802, 107.163},
645  {290.471, 107.257})
646  .CubicCurveTo({289.463, 107.544}, {288.455, 107.839},
647  {287.449, 108.139})
648  .CubicCurveTo({286.476, 108.431}, {285.506, 108.73},
649  {284.536, 109.035})
650  .CubicCurveTo({283.674, 109.304}, {282.812, 109.579},
651  {281.952, 109.859})
652  .CubicCurveTo({281.177, 110.112}, {280.406, 110.377},
653  {279.633, 110.638})
654  .CubicCurveTo({278.458, 111.037}, {277.256, 111.449},
655  {276.803, 111.607})
656  .CubicCurveTo({276.76, 111.622}, {276.716, 111.637},
657  {276.672, 111.653})
658  .CubicCurveTo({275.017, 112.239}, {273.365, 112.836},
659  {271.721, 113.463})
660  .LineTo({271.717, 113.449})
661  .CubicCurveTo({271.496, 113.496}, {271.238, 113.559},
662  {270.963, 113.628})
663  .CubicCurveTo({270.893, 113.645}, {270.822, 113.663},
664  {270.748, 113.682})
665  .CubicCurveTo({270.468, 113.755}, {270.169, 113.834},
666  {269.839, 113.926})
667  .CubicCurveTo({269.789, 113.94}, {269.732, 113.957},
668  {269.681, 113.972})
669  .CubicCurveTo({269.391, 114.053}, {269.081, 114.143},
670  {268.756, 114.239})
671  .CubicCurveTo({268.628, 114.276}, {268.5, 114.314},
672  {268.367, 114.354})
673  .CubicCurveTo({268.172, 114.412}, {267.959, 114.478},
674  {267.752, 114.54})
675  .CubicCurveTo({263.349, 115.964}, {258.058, 117.695},
676  {253.564, 119.252})
677  .CubicCurveTo({253.556, 119.255}, {253.547, 119.258},
678  {253.538, 119.261})
679  .CubicCurveTo({251.844, 119.849}, {250.056, 120.474},
680  {248.189, 121.131})
681  .CubicCurveTo({248, 121.197}, {247.812, 121.264}, {247.621, 121.331})
682  .CubicCurveTo({247.079, 121.522}, {246.531, 121.715},
683  {245.975, 121.912})
684  .CubicCurveTo({245.554, 122.06}, {245.126, 122.212},
685  {244.698, 122.364})
686  .CubicCurveTo({244.071, 122.586}, {243.437, 122.811},
687  {242.794, 123.04})
688  .CubicCurveTo({242.189, 123.255}, {241.58, 123.472},
689  {240.961, 123.693})
690  .CubicCurveTo({240.659, 123.801}, {240.357, 123.909},
691  {240.052, 124.018})
692  .CubicCurveTo({239.12, 124.351}, {238.18, 124.687}, {237.22, 125.032})
693  .LineTo({237.164, 125.003})
694  .CubicCurveTo({236.709, 125.184}, {236.262, 125.358},
695  {235.81, 125.538})
696  .CubicCurveTo({235.413, 125.68}, {234.994, 125.832},
697  {234.592, 125.977})
698  .CubicCurveTo({234.592, 125.977}, {234.591, 125.977},
699  {234.59, 125.977})
700  .CubicCurveTo({222.206, 130.435}, {207.708, 135.753},
701  {192.381, 141.429})
702  .CubicCurveTo({162.77, 151.336}, {122.17, 156.894}, {84.1123, 160})
703  .LineTo({360, 160})
704  .LineTo({360, 119.256})
705  .LineTo({360, 106.332})
706  .LineTo({360, 96.6307})
707  .CubicCurveTo({359.978, 96.6317}, {359.956, 96.6326},
708  {359.934, 96.6335})
709  .Close()
710  .MoveTo({337.336, 124.143})
711  .CubicCurveTo({337.274, 122.359}, {338.903, 121.511},
712  {338.903, 121.511})
713  .CubicCurveTo({338.903, 121.511}, {338.96, 123.303},
714  {337.336, 124.143})
715  .Close()
716  .MoveTo({340.082, 121.849})
717  .CubicCurveTo({340.074, 121.917}, {340.062, 121.992},
718  {340.046, 122.075})
719  .CubicCurveTo({340.039, 122.109}, {340.031, 122.142},
720  {340.023, 122.177})
721  .CubicCurveTo({340.005, 122.26}, {339.98, 122.346},
722  {339.952, 122.437})
723  .CubicCurveTo({339.941, 122.473}, {339.931, 122.507},
724  {339.918, 122.544})
725  .CubicCurveTo({339.873, 122.672}, {339.819, 122.804},
726  {339.75, 122.938})
727  .CubicCurveTo({339.747, 122.944}, {339.743, 122.949},
728  {339.74, 122.955})
729  .CubicCurveTo({339.674, 123.08}, {339.593, 123.205},
730  {339.501, 123.328})
731  .CubicCurveTo({339.473, 123.366}, {339.441, 123.401},
732  {339.41, 123.438})
733  .CubicCurveTo({339.332, 123.534}, {339.243, 123.625},
734  {339.145, 123.714})
735  .CubicCurveTo({339.105, 123.75}, {339.068, 123.786},
736  {339.025, 123.821})
737  .CubicCurveTo({338.881, 123.937}, {338.724, 124.048},
738  {338.539, 124.143})
739  .CubicCurveTo({338.532, 123.959}, {338.554, 123.79},
740  {338.58, 123.626})
741  .CubicCurveTo({338.58, 123.625}, {338.58, 123.625}, {338.58, 123.625})
742  .CubicCurveTo({338.607, 123.455}, {338.65, 123.299},
743  {338.704, 123.151})
744  .CubicCurveTo({338.708, 123.14}, {338.71, 123.127},
745  {338.714, 123.117})
746  .CubicCurveTo({338.769, 122.971}, {338.833, 122.838},
747  {338.905, 122.712})
748  .CubicCurveTo({338.911, 122.702}, {338.916, 122.69200000000001},
749  {338.922, 122.682})
750  .CubicCurveTo({338.996, 122.557}, {339.072, 122.444},
751  {339.155, 122.34})
752  .CubicCurveTo({339.161, 122.333}, {339.166, 122.326},
753  {339.172, 122.319})
754  .CubicCurveTo({339.256, 122.215}, {339.339, 122.12},
755  {339.425, 122.037})
756  .CubicCurveTo({339.428, 122.033}, {339.431, 122.03},
757  {339.435, 122.027})
758  .CubicCurveTo({339.785, 121.687}, {340.106, 121.511},
759  {340.106, 121.511})
760  .CubicCurveTo({340.106, 121.511}, {340.107, 121.645},
761  {340.082, 121.849})
762  .Close()
763  .MoveTo({340.678, 113.245})
764  .CubicCurveTo({340.594, 113.488}, {340.356, 113.655},
765  {340.135, 113.775})
766  .CubicCurveTo({339.817, 113.948}, {339.465, 114.059},
767  {339.115, 114.151})
768  .CubicCurveTo({338.251, 114.379}, {337.34, 114.516},
769  {336.448, 114.516})
770  .CubicCurveTo({335.761, 114.516}, {335.072, 114.527},
771  {334.384, 114.513})
772  .CubicCurveTo({334.125, 114.508}, {333.862, 114.462},
773  {333.605, 114.424})
774  .CubicCurveTo({332.865, 114.318}, {332.096, 114.184},
775  {331.41, 113.883})
776  .CubicCurveTo({330.979, 113.695}, {330.442, 113.34},
777  {330.672, 112.813})
778  .CubicCurveTo({331.135, 111.755}, {333.219, 112.946},
779  {334.526, 113.833})
780  .CubicCurveTo({334.54, 113.816}, {334.554, 113.8}, {334.569, 113.784})
781  .CubicCurveTo({333.38, 112.708}, {331.749, 110.985},
782  {332.76, 110.402})
783  .CubicCurveTo({333.769, 109.82}, {334.713, 111.93},
784  {335.228, 113.395})
785  .CubicCurveTo({334.915, 111.889}, {334.59, 109.636},
786  {335.661, 109.592})
787  .CubicCurveTo({336.733, 109.636}, {336.408, 111.889},
788  {336.07, 113.389})
789  .CubicCurveTo({336.609, 111.93}, {337.553, 109.82},
790  {338.563, 110.402})
791  .CubicCurveTo({339.574, 110.984}, {337.942, 112.708},
792  {336.753, 113.784})
793  .CubicCurveTo({336.768, 113.8}, {336.782, 113.816},
794  {336.796, 113.833})
795  .CubicCurveTo({338.104, 112.946}, {340.187, 111.755},
796  {340.65, 112.813})
797  .CubicCurveTo({340.71, 112.95}, {340.728, 113.102},
798  {340.678, 113.245})
799  .Close()
800  .MoveTo({346.357, 106.771})
801  .CubicCurveTo({346.295, 104.987}, {347.924, 104.139},
802  {347.924, 104.139})
803  .CubicCurveTo({347.924, 104.139}, {347.982, 105.931},
804  {346.357, 106.771})
805  .Close()
806  .MoveTo({347.56, 106.771})
807  .CubicCurveTo({347.498, 104.987}, {349.127, 104.139},
808  {349.127, 104.139})
809  .CubicCurveTo({349.127, 104.139}, {349.185, 105.931},
810  {347.56, 106.771})
811  .Close()
812  .TakePath();
813  Entity entity;
814  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
815  entity.SetContents(SolidColorContents::Make(path, Color::Red()));
816  ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
817 }

References impeller::Close(), impeller::LineTo(), impeller::SolidColorContents::Make(), impeller::Matrix::MakeScale(), impeller::PathBuilder::MoveTo(), impeller::Color::Red(), impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [306/419]

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

Definition at line 523 of file entity_unittests.cc.

523  {
524  // Compare with https://fiddle.skia.org/c/b3625f26122c9de7afe7794fcf25ead3
525  Path path =
526  PathBuilder{}
527  .MoveTo({237.164, 125.003})
528  .CubicCurveTo({236.709, 125.184}, {236.262, 125.358},
529  {235.81, 125.538})
530  .CubicCurveTo({235.413, 125.68}, {234.994, 125.832},
531  {234.592, 125.977})
532  .CubicCurveTo({234.592, 125.977}, {234.591, 125.977},
533  {234.59, 125.977})
534  .CubicCurveTo({222.206, 130.435}, {207.708, 135.753},
535  {192.381, 141.429})
536  .CubicCurveTo({162.77, 151.336}, {122.17, 156.894}, {84.1123, 160})
537  .Close()
538  .TakePath();
539  Entity entity;
540  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
541  entity.SetContents(SolidColorContents::Make(path, Color::Red()));
542  ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
543 }

References impeller::Close(), impeller::SolidColorContents::Make(), impeller::Matrix::MakeScale(), impeller::PathBuilder::MoveTo(), impeller::Color::Red(), impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [307/419]

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

Definition at line 2706 of file entity_unittests.cc.

2706  {
2707  auto content_context = GetContentContext();
2708  auto default_color_burn = content_context->GetMorphologyFilterPipeline({
2709  .color_attachment_pixel_format = PixelFormat::kR8G8B8A8UNormInt,
2710  });
2711 
2712  auto decal_supported = static_cast<Scalar>(
2713  GetContext()->GetCapabilities()->SupportsDecalSamplerAddressMode());
2714  std::vector<Scalar> expected_constants = {decal_supported};
2715  ASSERT_EQ(default_color_burn->GetDescriptor().GetSpecializationConstants(),
2716  expected_constants);
2717 }

References impeller::kR8G8B8A8UNormInt.

◆ TEST_P() [308/419]

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

Definition at line 1688 of file entity_unittests.cc.

1688  {
1689  auto fill = std::make_shared<SolidColorContents>();
1690  fill->SetColor(Color::CornflowerBlue());
1691  fill->SetGeometry(
1692  Geometry::MakeRect(Rect::MakeLTRB(-1000, -1000, -900, -900)));
1693 
1694  Entity entity;
1695  entity.SetContents(fill);
1696 
1697  // Even though the entity is offscreen, this should still render because we do
1698  // not compute the coverage intersection by default.
1699  EXPECT_TRUE(entity.ShouldRender(Rect::MakeLTRB(0, 0, 100, 100)));
1700 }

References impeller::Color::CornflowerBlue(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Geometry::MakeRect(), impeller::Entity::SetContents(), and impeller::Entity::ShouldRender().

◆ TEST_P() [309/419]

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

Definition at line 1417 of file entity_unittests.cc.

1417  {
1418  // Draws the image as four squares stiched together.
1419  auto atlas = CreateTextureForFixture("bay_bridge.jpg");
1420  auto size = atlas->GetSize();
1421  // Divide image into four quadrants.
1422  Scalar half_width = size.width / 2;
1423  Scalar half_height = size.height / 2;
1424  std::vector<Rect> texture_coordinates = {
1425  Rect::MakeLTRB(0, 0, half_width, half_height),
1426  Rect::MakeLTRB(half_width, 0, size.width, half_height),
1427  Rect::MakeLTRB(0, half_height, half_width, size.height),
1428  Rect::MakeLTRB(half_width, half_height, size.width, size.height)};
1429  // Position quadrants adjacent to eachother.
1430  std::vector<Matrix> transforms = {
1431  Matrix::MakeTranslation({0, 0, 0}),
1432  Matrix::MakeTranslation({half_width, 0, 0}),
1433  Matrix::MakeTranslation({0, half_height, 0}),
1434  Matrix::MakeTranslation({half_width, half_height, 0})};
1435  std::shared_ptr<AtlasContents> contents = std::make_shared<AtlasContents>();
1436 
1437  contents->SetTransforms(std::move(transforms));
1438  contents->SetTextureCoordinates(std::move(texture_coordinates));
1439  contents->SetTexture(atlas);
1440  contents->SetBlendMode(BlendMode::kSource);
1441 
1442  Entity e;
1443  e.SetTransform(Matrix::MakeScale(GetContentScale()));
1444  e.SetContents(contents);
1445 
1446  ASSERT_TRUE(OpenPlaygroundHere(std::move(e)));
1447 }

References impeller::kSource, impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [310/419]

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

Definition at line 1593 of file entity_unittests.cc.

1593  {
1594  auto atlas = CreateTextureForFixture("bay_bridge.jpg");
1595  auto size = atlas->GetSize();
1596  std::vector<Rect> texture_coordinates = {
1597  Rect::MakeLTRB(0, 0, size.width, size.height)};
1598  std::vector<Matrix> transforms = {Matrix::MakeTranslation({0, 0, 0})};
1599  std::shared_ptr<AtlasContents> contents = std::make_shared<AtlasContents>();
1600 
1601  contents->SetTransforms(std::move(transforms));
1602  contents->SetTextureCoordinates(std::move(texture_coordinates));
1603  contents->SetTexture(atlas);
1604  contents->SetBlendMode(BlendMode::kSource);
1605 
1606  Entity e;
1607  e.SetTransform(Matrix::MakeScale(GetContentScale()));
1608  e.SetContents(contents);
1609 
1610  ASSERT_TRUE(OpenPlaygroundHere(std::move(e)));
1611 }

References impeller::kSource, impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [311/419]

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

Definition at line 1520 of file entity_unittests.cc.

1520  {
1521  auto atlas = CreateTextureForFixture("bay_bridge.jpg");
1522  auto size = atlas->GetSize();
1523 
1524  Scalar half_width = size.width / 2;
1525  Scalar half_height = size.height / 2;
1526  std::vector<Rect> texture_coordinates = {
1527  Rect::MakeLTRB(0, 0, half_width, half_height),
1528  Rect::MakeLTRB(half_width, 0, size.width, half_height),
1529  Rect::MakeLTRB(0, half_height, half_width, size.height),
1530  Rect::MakeLTRB(half_width, half_height, size.width, size.height)};
1531  std::vector<Matrix> transforms = {
1532  Matrix::MakeTranslation({0, 0, 0}),
1533  Matrix::MakeTranslation({half_width, 0, 0}),
1534  Matrix::MakeTranslation({0, half_height, 0}),
1535  Matrix::MakeTranslation({half_width, half_height, 0})};
1536 
1537  std::shared_ptr<AtlasContents> contents = std::make_shared<AtlasContents>();
1538 
1539  contents->SetTransforms(std::move(transforms));
1540  contents->SetTextureCoordinates(std::move(texture_coordinates));
1541  contents->SetTexture(atlas);
1542  contents->SetBlendMode(BlendMode::kSource);
1543 
1544  auto transform = Matrix::MakeScale(GetContentScale());
1545  Entity e;
1546  e.SetTransform(transform);
1547  e.SetContents(contents);
1548 
1549  ASSERT_EQ(contents->GetCoverage(e).value(),
1550  Rect::MakeSize(size).TransformBounds(transform));
1551 
1552  contents->SetCullRect(Rect::MakeLTRB(0, 0, 10, 10));
1553 
1554  ASSERT_EQ(contents->GetCoverage(e).value(),
1555  Rect::MakeLTRB(0, 0, 10, 10).TransformBounds(transform));
1556 }

References impeller::kSource, impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeScale(), impeller::TRect< Scalar >::MakeSize(), impeller::Matrix::MakeTranslation(), impeller::Entity::SetContents(), impeller::Entity::SetTransform(), and impeller::TRect< T >::TransformBounds().

◆ TEST_P() [312/419]

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

Definition at line 1449 of file entity_unittests.cc.

1449  {
1450  // Draws the image as four squares stiched together.
1451  auto atlas = CreateTextureForFixture("bay_bridge.jpg");
1452  auto size = atlas->GetSize();
1453  // Divide image into four quadrants.
1454  Scalar half_width = size.width / 2;
1455  Scalar half_height = size.height / 2;
1456  std::vector<Rect> texture_coordinates = {
1457  Rect::MakeLTRB(0, 0, half_width, half_height),
1458  Rect::MakeLTRB(half_width, 0, size.width, half_height),
1459  Rect::MakeLTRB(0, half_height, half_width, size.height),
1460  Rect::MakeLTRB(half_width, half_height, size.width, size.height)};
1461  // Position quadrants adjacent to eachother.
1462  std::vector<Matrix> transforms = {
1463  Matrix::MakeTranslation({0, 0, 0}),
1464  Matrix::MakeTranslation({half_width, 0, 0}),
1465  Matrix::MakeTranslation({0, half_height, 0}),
1466  Matrix::MakeTranslation({half_width, half_height, 0})};
1467  std::vector<Color> colors = {Color::Red(), Color::Green(), Color::Blue(),
1468  Color::Yellow()};
1469  std::shared_ptr<AtlasContents> contents = std::make_shared<AtlasContents>();
1470 
1471  contents->SetTransforms(std::move(transforms));
1472  contents->SetTextureCoordinates(std::move(texture_coordinates));
1473  contents->SetTexture(atlas);
1474  contents->SetColors(colors);
1475  contents->SetBlendMode(BlendMode::kModulate);
1476 
1477  Entity e;
1478  e.SetTransform(Matrix::MakeScale(GetContentScale()));
1479  e.SetContents(contents);
1480 
1481  ASSERT_TRUE(OpenPlaygroundHere(std::move(e)));
1482 }

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::SetTransform(), and impeller::Color::Yellow().

◆ TEST_P() [313/419]

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

Definition at line 1484 of file entity_unittests.cc.

1484  {
1485  // Draws the image as four squares stiched together. Because blend modes
1486  // aren't implented this ends up as four solid color blocks.
1487  auto atlas = CreateTextureForFixture("bay_bridge.jpg");
1488  auto size = atlas->GetSize();
1489  // Divide image into four quadrants.
1490  Scalar half_width = size.width / 2;
1491  Scalar half_height = size.height / 2;
1492  std::vector<Rect> texture_coordinates = {
1493  Rect::MakeLTRB(0, 0, half_width, half_height),
1494  Rect::MakeLTRB(half_width, 0, size.width, half_height),
1495  Rect::MakeLTRB(0, half_height, half_width, size.height),
1496  Rect::MakeLTRB(half_width, half_height, size.width, size.height)};
1497  // Position quadrants adjacent to eachother.
1498  std::vector<Matrix> transforms = {
1499  Matrix::MakeTranslation({0, 0, 0}),
1500  Matrix::MakeTranslation({half_width, 0, 0}),
1501  Matrix::MakeTranslation({0, half_height, 0}),
1502  Matrix::MakeTranslation({half_width, half_height, 0})};
1503  std::vector<Color> colors = {Color::Red(), Color::Green(), Color::Blue(),
1504  Color::Yellow()};
1505  std::shared_ptr<AtlasContents> contents = std::make_shared<AtlasContents>();
1506 
1507  contents->SetTransforms(std::move(transforms));
1508  contents->SetTextureCoordinates(std::move(texture_coordinates));
1509  contents->SetTexture(atlas);
1510  contents->SetColors(colors);
1511  contents->SetBlendMode(BlendMode::kSourceATop);
1512 
1513  Entity e;
1514  e.SetTransform(Matrix::MakeScale(GetContentScale()));
1515  e.SetContents(contents);
1516 
1517  ASSERT_TRUE(OpenPlaygroundHere(std::move(e)));
1518 }

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::SetTransform(), and impeller::Color::Yellow().

◆ TEST_P() [314/419]

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

Definition at line 1558 of file entity_unittests.cc.

1558  {
1559  // Draws the image as four squares stiched together slightly
1560  // opaque
1561  auto atlas = CreateTextureForFixture("bay_bridge.jpg");
1562  auto size = atlas->GetSize();
1563  // Divide image into four quadrants.
1564  Scalar half_width = size.width / 2;
1565  Scalar half_height = size.height / 2;
1566  std::vector<Rect> texture_coordinates = {
1567  Rect::MakeLTRB(0, 0, half_width, half_height),
1568  Rect::MakeLTRB(half_width, 0, size.width, half_height),
1569  Rect::MakeLTRB(0, half_height, half_width, size.height),
1570  Rect::MakeLTRB(half_width, half_height, size.width, size.height)};
1571  // Position quadrants adjacent to eachother.
1572  std::vector<Matrix> transforms = {
1573  Matrix::MakeTranslation({0, 0, 0}),
1574  Matrix::MakeTranslation({half_width, 0, 0}),
1575  Matrix::MakeTranslation({0, half_height, 0}),
1576  Matrix::MakeTranslation({half_width, half_height, 0})};
1577 
1578  std::shared_ptr<AtlasContents> contents = std::make_shared<AtlasContents>();
1579 
1580  contents->SetTransforms(std::move(transforms));
1581  contents->SetTextureCoordinates(std::move(texture_coordinates));
1582  contents->SetTexture(atlas);
1583  contents->SetBlendMode(BlendMode::kSource);
1584  contents->SetAlpha(0.5);
1585 
1586  Entity e;
1587  e.SetTransform(Matrix::MakeScale(GetContentScale()));
1588  e.SetContents(contents);
1589 
1590  ASSERT_TRUE(OpenPlaygroundHere(std::move(e)));
1591 }

References impeller::kSource, impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [315/419]

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

Definition at line 187 of file entity_unittests.cc.

187  {
188  // Both a red and a blue box should appear if the pass merging has worked
189  // correctly.
190 
191  EntityPass pass;
192  auto subpass = CreatePassWithRectPath(Rect::MakeLTRB(0, 0, 100, 100),
193  Rect::MakeLTRB(50, 50, 150, 150),
194  ContentBoundsPromise::kUnknown, true);
195  pass.AddSubpass(std::move(subpass));
196 
197  Entity entity;
198  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
199  auto contents = std::make_unique<SolidColorContents>();
200  contents->SetGeometry(Geometry::MakeRect(Rect::MakeLTRB(100, 100, 200, 200)));
201  contents->SetColor(Color::Blue());
202  entity.SetContents(std::move(contents));
203 
204  pass.AddEntity(std::move(entity));
205 
206  ASSERT_TRUE(OpenPlaygroundHere(pass));
207 }

References impeller::EntityPass::AddEntity(), impeller::EntityPass::AddSubpass(), impeller::Color::Blue(), CreatePassWithRectPath(), impeller::kUnknown, impeller::TRect< Scalar >::MakeLTRB(), impeller::Geometry::MakeRect(), impeller::Matrix::MakeScale(), impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [316/419]

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

Definition at line 209 of file entity_unittests.cc.

209  {
210  // Rect is drawn entirely in negative area.
211  auto pass = CreatePassWithRectPath(Rect::MakeLTRB(-200, -200, -100, -100),
212  std::nullopt);
213 
214  // Without coverage limit.
215  {
216  auto pass_coverage = pass->GetElementsCoverage(std::nullopt);
217  ASSERT_TRUE(pass_coverage.has_value());
218  ASSERT_RECT_NEAR(pass_coverage.value(),
219  Rect::MakeLTRB(-200, -200, -100, -100));
220  }
221 
222  // With limit that doesn't overlap.
223  {
224  auto pass_coverage =
225  pass->GetElementsCoverage(Rect::MakeLTRB(0, 0, 100, 100));
226  ASSERT_FALSE(pass_coverage.has_value());
227  }
228 
229  // With limit that partially overlaps.
230  {
231  auto pass_coverage =
232  pass->GetElementsCoverage(Rect::MakeLTRB(-150, -150, 0, 0));
233  ASSERT_TRUE(pass_coverage.has_value());
234  ASSERT_RECT_NEAR(pass_coverage.value(),
235  Rect::MakeLTRB(-150, -150, -100, -100));
236  }
237 }

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

◆ TEST_P() [317/419]

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

Definition at line 124 of file entity_unittests.cc.

124  {
125  EntityPass pass;
126 
127  auto subpass0 = CreatePassWithRectPath(Rect::MakeLTRB(0, 0, 100, 100),
128  Rect::MakeLTRB(50, 50, 150, 150));
129  auto subpass1 = CreatePassWithRectPath(Rect::MakeLTRB(500, 500, 1000, 1000),
130  Rect::MakeLTRB(800, 800, 900, 900));
131 
132  auto subpass0_coverage =
133  pass.GetSubpassCoverage(*subpass0.get(), std::nullopt);
134  ASSERT_TRUE(subpass0_coverage.has_value());
135  ASSERT_RECT_NEAR(subpass0_coverage.value(), Rect::MakeLTRB(50, 50, 100, 100));
136 
137  auto subpass1_coverage =
138  pass.GetSubpassCoverage(*subpass1.get(), std::nullopt);
139  ASSERT_TRUE(subpass1_coverage.has_value());
140  ASSERT_RECT_NEAR(subpass1_coverage.value(),
141  Rect::MakeLTRB(800, 800, 900, 900));
142 
143  pass.AddSubpass(std::move(subpass0));
144  pass.AddSubpass(std::move(subpass1));
145 
146  auto coverage = pass.GetElementsCoverage(std::nullopt);
147  ASSERT_TRUE(coverage.has_value());
148  ASSERT_RECT_NEAR(coverage.value(), Rect::MakeLTRB(50, 50, 900, 900));
149 }

References impeller::EntityPass::AddSubpass(), ASSERT_RECT_NEAR, CreatePassWithRectPath(), impeller::EntityPass::GetElementsCoverage(), impeller::EntityPass::GetSubpassCoverage(), and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST_P() [318/419]

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

Definition at line 151 of file entity_unittests.cc.

151  {
152  EntityPass pass;
153 
154  auto subpass0 = //
155  CreatePassWithRectPath(Rect::MakeLTRB(10, 10, 90, 90),
156  Rect::MakeLTRB(5, 5, 95, 95),
157  ContentBoundsPromise::kContainsContents);
158  auto subpass1 = //
159  CreatePassWithRectPath(Rect::MakeLTRB(500, 500, 1000, 1000),
160  Rect::MakeLTRB(495, 495, 1005, 1005),
161  ContentBoundsPromise::kContainsContents);
162 
163  auto subpass0_coverage =
164  pass.GetSubpassCoverage(*subpass0.get(), std::nullopt);
165  EXPECT_TRUE(subpass0_coverage.has_value());
166  // Result should be the overridden bounds
167  // (we lied about them being snug, but the property is respected)
168  EXPECT_RECT_NEAR(subpass0_coverage.value(), Rect::MakeLTRB(5, 5, 95, 95));
169 
170  auto subpass1_coverage =
171  pass.GetSubpassCoverage(*subpass1.get(), std::nullopt);
172  EXPECT_TRUE(subpass1_coverage.has_value());
173  // Result should be the overridden bounds
174  // (we lied about them being snug, but the property is respected)
175  EXPECT_RECT_NEAR(subpass1_coverage.value(),
176  Rect::MakeLTRB(495, 495, 1005, 1005));
177 
178  pass.AddSubpass(std::move(subpass0));
179  pass.AddSubpass(std::move(subpass1));
180 
181  auto coverage = pass.GetElementsCoverage(std::nullopt);
182  EXPECT_TRUE(coverage.has_value());
183  // This result should be the union of the overridden bounds
184  EXPECT_RECT_NEAR(coverage.value(), Rect::MakeLTRB(5, 5, 1005, 1005));
185 }

References impeller::EntityPass::AddSubpass(), CreatePassWithRectPath(), EXPECT_RECT_NEAR, impeller::EntityPass::GetElementsCoverage(), impeller::EntityPass::GetSubpassCoverage(), impeller::kContainsContents, and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST_P() [319/419]

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

Definition at line 2802 of file entity_unittests.cc.

2802  {
2803  if (GetParam() != PlaygroundBackend::kVulkan) {
2804  GTEST_SKIP() << "Validation is only fatal on Vulkan backend.";
2805  }
2806  EXPECT_DEATH(
2807  // The easiest way to trigger a validation error is to try to compile
2808  // a shader with an unsupported pixel format.
2809  GetContentContext()->GetBlendColorBurnPipeline({
2810  .color_attachment_pixel_format = PixelFormat::kUnknown,
2811  .has_depth_stencil_attachments = false,
2812  }),
2813  "");
2814 }

References impeller::kUnknown, and impeller::kVulkan.

◆ TEST_P() [320/419]

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

Definition at line 2764 of file entity_unittests.cc.

2764  {
2765  RenderTarget target;
2766  testing::MockRenderPass mock_pass(GetContext(), target);
2767 
2768  auto get_result = [this, &mock_pass](const Path& path) {
2769  auto geometry = Geometry::MakeFillPath(
2770  path, /* inner rect */ Rect::MakeLTRB(0, 0, 100, 100));
2771  return geometry->GetPositionBuffer(*GetContentContext(), {}, mock_pass);
2772  };
2773 
2774  // Convex path
2775  {
2776  GeometryResult result =
2777  get_result(PathBuilder{}
2778  .AddRect(Rect::MakeLTRB(0, 0, 100, 100))
2779  .SetConvexity(Convexity::kConvex)
2780  .TakePath());
2781  EXPECT_EQ(result.mode, GeometryResult::Mode::kNormal);
2782  }
2783 
2784  // Concave path
2785  {
2786  Path path = PathBuilder{}
2787  .MoveTo({0, 0})
2788  .LineTo({100, 0})
2789  .LineTo({100, 100})
2790  .LineTo({50, 50})
2791  .Close()
2792  .TakePath();
2793  GeometryResult result = get_result(path);
2794  if constexpr (ContentContext::kEnableStencilThenCover) {
2795  EXPECT_EQ(result.mode, GeometryResult::Mode::kNonZero);
2796  } else {
2797  EXPECT_EQ(result.mode, GeometryResult::Mode::kNormal);
2798  }
2799  }
2800 }

References impeller::PathBuilder::AddRect(), impeller::Close(), impeller::kConvex, impeller::ContentContext::kEnableStencilThenCover, impeller::GeometryResult::kNonZero, impeller::GeometryResult::kNormal, impeller::LineTo(), impeller::Geometry::MakeFillPath(), impeller::TRect< Scalar >::MakeLTRB(), impeller::GeometryResult::mode, and impeller::PathBuilder::MoveTo().

◆ TEST_P() [321/419]

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

Definition at line 239 of file entity_unittests.cc.

239  {
240  auto image = CreateTextureForFixture("boston.jpg");
241  auto filter = ColorFilterContents::MakeBlend(BlendMode::kSoftLight,
242  FilterInput::Make({image}));
243 
244  // Without the crop rect (default behavior).
245  {
246  auto actual = filter->GetCoverage({});
247  auto expected = Rect::MakeSize(image->GetSize());
248 
249  ASSERT_TRUE(actual.has_value());
250  ASSERT_RECT_NEAR(actual.value(), expected);
251  }
252 
253  // With the crop rect.
254  {
255  auto expected = Rect::MakeLTRB(50, 50, 100, 100);
256  filter->SetCoverageHint(expected);
257  auto actual = filter->GetCoverage({});
258 
259  ASSERT_TRUE(actual.has_value());
260  ASSERT_RECT_NEAR(actual.value(), expected);
261  }
262 }

References ASSERT_RECT_NEAR, impeller::kSoftLight, impeller::FilterInput::Make(), impeller::ColorFilterContents::MakeBlend(), impeller::TRect< Scalar >::MakeLTRB(), and impeller::TRect< Scalar >::MakeSize().

◆ TEST_P() [322/419]

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

Definition at line 1023 of file entity_unittests.cc.

1023  {
1024  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
1025  auto boston = CreateTextureForFixture("boston.jpg");
1026  auto kalimba = CreateTextureForFixture("kalimba.jpg");
1027  ASSERT_TRUE(bridge && boston && kalimba);
1028 
1029  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1030  auto fi_bridge = FilterInput::Make(bridge);
1031  auto fi_boston = FilterInput::Make(boston);
1032  auto fi_kalimba = FilterInput::Make(kalimba);
1033 
1034  std::shared_ptr<FilterContents> blend0 = ColorFilterContents::MakeBlend(
1035  BlendMode::kModulate, {fi_kalimba, fi_boston});
1036 
1037  auto blend1 = ColorFilterContents::MakeBlend(
1038  BlendMode::kScreen,
1039  {FilterInput::Make(blend0), fi_bridge, fi_bridge, fi_bridge});
1040 
1041  Entity entity;
1042  entity.SetTransform(Matrix::MakeScale(GetContentScale()) *
1043  Matrix::MakeTranslation({500, 300}) *
1044  Matrix::MakeScale(Vector2{0.5, 0.5}));
1045  entity.SetContents(blend1);
1046  return entity.Render(context, pass);
1047  };
1048  ASSERT_TRUE(OpenPlaygroundHere(callback));
1049 }

References impeller::kModulate, impeller::kScreen, impeller::FilterInput::Make(), impeller::ColorFilterContents::MakeBlend(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), and impeller::Entity::SetTransform().

◆ TEST_P() [323/419]

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

Definition at line 1051 of file entity_unittests.cc.

1051  {
1052  auto boston =
1053  CreateTextureForFixture("boston.jpg", /*enable_mipmapping=*/true);
1054  ASSERT_TRUE(boston);
1055 
1056  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1057  const char* input_type_names[] = {"Texture", "Solid Color"};
1058  const char* blur_type_names[] = {"Image blur", "Mask blur"};
1059  const char* pass_variation_names[] = {"New"};
1060  const char* blur_style_names[] = {"Normal", "Solid", "Outer", "Inner"};
1061  const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
1062  const FilterContents::BlurStyle blur_styles[] = {
1063  FilterContents::BlurStyle::kNormal, FilterContents::BlurStyle::kSolid,
1064  FilterContents::BlurStyle::kOuter, FilterContents::BlurStyle::kInner};
1065  const Entity::TileMode tile_modes[] = {
1066  Entity::TileMode::kClamp, Entity::TileMode::kRepeat,
1067  Entity::TileMode::kMirror, Entity::TileMode::kDecal};
1068 
1069  // UI state.
1070  static int selected_input_type = 0;
1071  static Color input_color = Color::Black();
1072  static int selected_blur_type = 0;
1073  static int selected_pass_variation = 0;
1074  static bool combined_sigma = false;
1075  static float blur_amount_coarse[2] = {0, 0};
1076  static float blur_amount_fine[2] = {10, 10};
1077  static int selected_blur_style = 0;
1078  static int selected_tile_mode = 3;
1079  static Color cover_color(1, 0, 0, 0.2);
1080  static Color bounds_color(0, 1, 0, 0.1);
1081  static float offset[2] = {500, 400};
1082  static float rotation = 0;
1083  static float scale[2] = {0.65, 0.65};
1084  static float skew[2] = {0, 0};
1085  static float path_rect[4] = {0, 0,
1086  static_cast<float>(boston->GetSize().width),
1087  static_cast<float>(boston->GetSize().height)};
1088 
1089  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1090  {
1091  ImGui::Combo("Input type", &selected_input_type, input_type_names,
1092  sizeof(input_type_names) / sizeof(char*));
1093  if (selected_input_type == 0) {
1094  ImGui::SliderFloat("Input opacity", &input_color.alpha, 0, 1);
1095  } else {
1096  ImGui::ColorEdit4("Input color",
1097  reinterpret_cast<float*>(&input_color));
1098  }
1099  ImGui::Combo("Blur type", &selected_blur_type, blur_type_names,
1100  sizeof(blur_type_names) / sizeof(char*));
1101  if (selected_blur_type == 0) {
1102  ImGui::Combo("Pass variation", &selected_pass_variation,
1103  pass_variation_names,
1104  sizeof(pass_variation_names) / sizeof(char*));
1105  }
1106  ImGui::Checkbox("Combined sigma", &combined_sigma);
1107  if (combined_sigma) {
1108  ImGui::SliderFloat("Sigma (coarse)", blur_amount_coarse, 0, 1000);
1109  ImGui::SliderFloat("Sigma (fine)", blur_amount_fine, 0, 10);
1110  blur_amount_coarse[1] = blur_amount_coarse[0];
1111  blur_amount_fine[1] = blur_amount_fine[0];
1112  } else {
1113  ImGui::SliderFloat2("Sigma (coarse)", blur_amount_coarse, 0, 1000);
1114  ImGui::SliderFloat2("Sigma (fine)", blur_amount_fine, 0, 10);
1115  }
1116  ImGui::Combo("Blur style", &selected_blur_style, blur_style_names,
1117  sizeof(blur_style_names) / sizeof(char*));
1118  ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
1119  sizeof(tile_mode_names) / sizeof(char*));
1120  ImGui::ColorEdit4("Cover color", reinterpret_cast<float*>(&cover_color));
1121  ImGui::ColorEdit4("Bounds color",
1122  reinterpret_cast<float*>(&bounds_color));
1123  ImGui::SliderFloat2("Translation", offset, 0,
1124  pass.GetRenderTargetSize().width);
1125  ImGui::SliderFloat("Rotation", &rotation, 0, kPi * 2);
1126  ImGui::SliderFloat2("Scale", scale, 0, 3);
1127  ImGui::SliderFloat2("Skew", skew, -3, 3);
1128  ImGui::SliderFloat4("Path XYWH", path_rect, -1000, 1000);
1129  }
1130  ImGui::End();
1131 
1132  auto blur_sigma_x = Sigma{blur_amount_coarse[0] + blur_amount_fine[0]};
1133  auto blur_sigma_y = Sigma{blur_amount_coarse[1] + blur_amount_fine[1]};
1134 
1135  std::shared_ptr<Contents> input;
1136  Size input_size;
1137 
1138  auto input_rect =
1139  Rect::MakeXYWH(path_rect[0], path_rect[1], path_rect[2], path_rect[3]);
1140  if (selected_input_type == 0) {
1141  auto texture = std::make_shared<TextureContents>();
1142  texture->SetSourceRect(Rect::MakeSize(boston->GetSize()));
1143  texture->SetDestinationRect(input_rect);
1144  texture->SetTexture(boston);
1145  texture->SetOpacity(input_color.alpha);
1146 
1147  input = texture;
1148  input_size = input_rect.GetSize();
1149  } else {
1150  auto fill = std::make_shared<SolidColorContents>();
1151  fill->SetColor(input_color);
1152  fill->SetGeometry(
1153  Geometry::MakeFillPath(PathBuilder{}.AddRect(input_rect).TakePath()));
1154 
1155  input = fill;
1156  input_size = input_rect.GetSize();
1157  }
1158 
1159  std::shared_ptr<FilterContents> blur;
1160  switch (selected_pass_variation) {
1161  case 0:
1162  blur = std::make_shared<GaussianBlurFilterContents>(
1163  blur_sigma_x.sigma, blur_sigma_y.sigma,
1164  tile_modes[selected_tile_mode], blur_styles[selected_blur_style],
1165  /*geometry=*/nullptr);
1166  blur->SetInputs({FilterInput::Make(input)});
1167  break;
1168  case 1:
1169  blur = FilterContents::MakeGaussianBlur(
1170  FilterInput::Make(input), blur_sigma_x, blur_sigma_y,
1171  tile_modes[selected_tile_mode], blur_styles[selected_blur_style]);
1172  break;
1173  };
1174  FML_CHECK(blur);
1175 
1176  auto mask_blur = FilterContents::MakeBorderMaskBlur(
1177  FilterInput::Make(input), blur_sigma_x, blur_sigma_y,
1178  blur_styles[selected_blur_style]);
1179 
1180  auto ctm = Matrix::MakeScale(GetContentScale()) *
1181  Matrix::MakeTranslation(Vector3(offset[0], offset[1])) *
1182  Matrix::MakeRotationZ(Radians(rotation)) *
1183  Matrix::MakeScale(Vector2(scale[0], scale[1])) *
1184  Matrix::MakeSkew(skew[0], skew[1]) *
1185  Matrix::MakeTranslation(-Point(input_size) / 2);
1186 
1187  auto target_contents = selected_blur_type == 0 ? blur : mask_blur;
1188 
1189  Entity entity;
1190  entity.SetContents(target_contents);
1191  entity.SetTransform(ctm);
1192 
1193  entity.Render(context, pass);
1194 
1195  // Renders a red "cover" rectangle that shows the original position of the
1196  // unfiltered input.
1197  Entity cover_entity;
1198  cover_entity.SetContents(SolidColorContents::Make(
1199  PathBuilder{}.AddRect(input_rect).TakePath(), cover_color));
1200  cover_entity.SetTransform(ctm);
1201 
1202  cover_entity.Render(context, pass);
1203 
1204  // Renders a green bounding rect of the target filter.
1205  Entity bounds_entity;
1206  std::optional<Rect> target_contents_coverage =
1207  target_contents->GetCoverage(entity);
1208  if (target_contents_coverage.has_value()) {
1209  bounds_entity.SetContents(SolidColorContents::Make(
1210  PathBuilder{}
1211  .AddRect(target_contents->GetCoverage(entity).value())
1212  .TakePath(),
1213  bounds_color));
1214  bounds_entity.SetTransform(Matrix());
1215 
1216  bounds_entity.Render(context, pass);
1217  }
1218 
1219  return true;
1220  };
1221  ASSERT_TRUE(OpenPlaygroundHere(callback));
1222 }

References impeller::PathBuilder::AddRect(), impeller::Color::alpha, impeller::Color::Black(), impeller::Entity::GetCoverage(), 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::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(), offset, impeller::Entity::Render(), scale, impeller::Entity::SetContents(), impeller::Entity::SetTransform(), and impeller::PathBuilder::TakePath().

◆ TEST_P() [324/419]

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

Definition at line 292 of file entity_unittests.cc.

292  {
293  auto geometry = Geometry::MakeRect(Rect::MakeXYWH(100, 100, 100, 100));
294  auto transform = Matrix::MakeScale({2.0, 2.0, 2.0});
295 
296  ASSERT_RECT_NEAR(geometry->GetCoverage(transform).value(),
297  Rect::MakeXYWH(200, 200, 200, 200));
298 }

References ASSERT_RECT_NEAR, impeller::Geometry::MakeRect(), impeller::Matrix::MakeScale(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST_P() [325/419]

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

Definition at line 2356 of file entity_unittests.cc.

2356  {
2357  Entity entity;
2358 
2359  // Texture contents can always accept opacity.
2360  auto texture_contents = std::make_shared<TextureContents>();
2361  texture_contents->SetOpacity(0.5);
2362  ASSERT_TRUE(texture_contents->CanInheritOpacity(entity));
2363 
2364  texture_contents->SetInheritedOpacity(0.5);
2365  ASSERT_EQ(texture_contents->GetOpacity(), 0.25);
2366  texture_contents->SetInheritedOpacity(0.5);
2367  ASSERT_EQ(texture_contents->GetOpacity(), 0.25);
2368 
2369  // Solid color contents can accept opacity if their geometry
2370  // doesn't overlap.
2371  auto solid_color = std::make_shared<SolidColorContents>();
2372  solid_color->SetGeometry(
2373  Geometry::MakeRect(Rect::MakeLTRB(100, 100, 200, 200)));
2374  solid_color->SetColor(Color::Blue().WithAlpha(0.5));
2375 
2376  ASSERT_TRUE(solid_color->CanInheritOpacity(entity));
2377 
2378  solid_color->SetInheritedOpacity(0.5);
2379  ASSERT_EQ(solid_color->GetColor().alpha, 0.25);
2380  solid_color->SetInheritedOpacity(0.5);
2381  ASSERT_EQ(solid_color->GetColor().alpha, 0.25);
2382 
2383  // Color source contents can accept opacity if their geometry
2384  // doesn't overlap.
2385  auto tiled_texture = std::make_shared<TiledTextureContents>();
2386  tiled_texture->SetGeometry(
2387  Geometry::MakeRect(Rect::MakeLTRB(100, 100, 200, 200)));
2388  tiled_texture->SetOpacityFactor(0.5);
2389 
2390  ASSERT_TRUE(tiled_texture->CanInheritOpacity(entity));
2391 
2392  tiled_texture->SetInheritedOpacity(0.5);
2393  ASSERT_EQ(tiled_texture->GetOpacityFactor(), 0.25);
2394  tiled_texture->SetInheritedOpacity(0.5);
2395  ASSERT_EQ(tiled_texture->GetOpacityFactor(), 0.25);
2396 
2397  // Text contents can accept opacity if the text frames do not
2398  // overlap
2399  SkFont font = flutter::testing::CreateTestFontOfSize(30);
2400  auto blob = SkTextBlob::MakeFromString("A", font);
2401  auto frame = MakeTextFrameFromTextBlobSkia(blob);
2402  auto lazy_glyph_atlas =
2403  std::make_shared<LazyGlyphAtlas>(TypographerContextSkia::Make());
2404  lazy_glyph_atlas->AddTextFrame(*frame, 1.0f);
2405 
2406  auto text_contents = std::make_shared<TextContents>();
2407  text_contents->SetTextFrame(frame);
2408  text_contents->SetColor(Color::Blue().WithAlpha(0.5));
2409 
2410  ASSERT_TRUE(text_contents->CanInheritOpacity(entity));
2411 
2412  text_contents->SetInheritedOpacity(0.5);
2413  ASSERT_EQ(text_contents->GetColor().alpha, 0.25);
2414  text_contents->SetInheritedOpacity(0.5);
2415  ASSERT_EQ(text_contents->GetColor().alpha, 0.25);
2416 
2417  // Clips and restores trivially accept opacity.
2418  ASSERT_TRUE(ClipContents().CanInheritOpacity(entity));
2419  ASSERT_TRUE(ClipRestoreContents().CanInheritOpacity(entity));
2420 
2421  // Runtime effect contents can't accept opacity.
2422  auto runtime_effect = std::make_shared<RuntimeEffectContents>();
2423  ASSERT_FALSE(runtime_effect->CanInheritOpacity(entity));
2424 }

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

◆ TEST_P() [326/419]

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

Definition at line 2538 of file entity_unittests.cc.

2538  {
2539  LinearGradientContents contents;
2540  contents.SetColors({Color::CornflowerBlue()});
2541  ASSERT_TRUE(contents.IsOpaque());
2542  contents.SetColors({Color::CornflowerBlue().WithAlpha(0.5)});
2543  ASSERT_FALSE(contents.IsOpaque());
2544  contents.SetColors({Color::CornflowerBlue()});
2545  contents.SetTileMode(Entity::TileMode::kDecal);
2546  ASSERT_FALSE(contents.IsOpaque());
2547 }

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

◆ TEST_P() [327/419]

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

Definition at line 1947 of file entity_unittests.cc.

1947  {
1948  auto image = CreateTextureForFixture("kalimba.jpg");
1949  ASSERT_TRUE(image);
1950 
1951  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1952  auto filtered =
1953  ColorFilterContents::MakeLinearToSrgbFilter(FilterInput::Make(image));
1954 
1955  // Define the entity that will serve as the control image as a Gaussian blur
1956  // filter with no filter at all.
1957  Entity entity_left;
1958  entity_left.SetTransform(Matrix::MakeScale(GetContentScale()) *
1959  Matrix::MakeTranslation({100, 300}) *
1960  Matrix::MakeScale(Vector2{0.5, 0.5}));
1961  auto unfiltered = FilterContents::MakeGaussianBlur(FilterInput::Make(image),
1962  Sigma{0}, Sigma{0});
1963  entity_left.SetContents(unfiltered);
1964 
1965  // Define the entity that will be filtered from linear to sRGB.
1966  Entity entity_right;
1967  entity_right.SetTransform(Matrix::MakeScale(GetContentScale()) *
1968  Matrix::MakeTranslation({500, 300}) *
1969  Matrix::MakeScale(Vector2{0.5, 0.5}));
1970  entity_right.SetContents(filtered);
1971  return entity_left.Render(context, pass) &&
1972  entity_right.Render(context, pass);
1973  };
1974 
1975  ASSERT_TRUE(OpenPlaygroundHere(callback));
1976 }

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::SetTransform().

◆ TEST_P() [328/419]

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

Definition at line 1926 of file entity_unittests.cc.

1926  {
1927  // Set up a simple color background.
1928  auto fill = std::make_shared<SolidColorContents>();
1929  fill->SetGeometry(Geometry::MakeFillPath(
1930  PathBuilder{}.AddRect(Rect::MakeXYWH(0, 0, 300, 400)).TakePath()));
1931  fill->SetColor(Color::MintCream());
1932 
1933  auto filter =
1934  ColorFilterContents::MakeLinearToSrgbFilter(FilterInput::Make(fill));
1935 
1936  Entity e;
1937  e.SetTransform(Matrix());
1938 
1939  // Confirm that the actual filter coverage matches the expected coverage.
1940  auto actual = filter->GetCoverage(e);
1941  auto expected = Rect::MakeXYWH(0, 0, 300, 400);
1942 
1943  ASSERT_TRUE(actual.has_value());
1944  ASSERT_RECT_NEAR(actual.value(), expected);
1945 }

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::SetTransform().

◆ TEST_P() [329/419]

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

Definition at line 1224 of file entity_unittests.cc.

1224  {
1225  auto boston = CreateTextureForFixture("boston.jpg");
1226  ASSERT_TRUE(boston);
1227 
1228  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1229  const char* morphology_type_names[] = {"Dilate", "Erode"};
1230  const FilterContents::MorphType morphology_types[] = {
1231  FilterContents::MorphType::kDilate, FilterContents::MorphType::kErode};
1232  static Color input_color = Color::Black();
1233  // UI state.
1234  static int selected_morphology_type = 0;
1235  static float radius[2] = {20, 20};
1236  static Color cover_color(1, 0, 0, 0.2);
1237  static Color bounds_color(0, 1, 0, 0.1);
1238  static float offset[2] = {500, 400};
1239  static float rotation = 0;
1240  static float scale[2] = {0.65, 0.65};
1241  static float skew[2] = {0, 0};
1242  static float path_rect[4] = {0, 0,
1243  static_cast<float>(boston->GetSize().width),
1244  static_cast<float>(boston->GetSize().height)};
1245  static float effect_transform_scale = 1;
1246 
1247  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1248  {
1249  ImGui::Combo("Morphology type", &selected_morphology_type,
1250  morphology_type_names,
1251  sizeof(morphology_type_names) / sizeof(char*));
1252  ImGui::SliderFloat2("Radius", radius, 0, 200);
1253  ImGui::SliderFloat("Input opacity", &input_color.alpha, 0, 1);
1254  ImGui::ColorEdit4("Cover color", reinterpret_cast<float*>(&cover_color));
1255  ImGui::ColorEdit4("Bounds color",
1256  reinterpret_cast<float*>(&bounds_color));
1257  ImGui::SliderFloat2("Translation", offset, 0,
1258  pass.GetRenderTargetSize().width);
1259  ImGui::SliderFloat("Rotation", &rotation, 0, kPi * 2);
1260  ImGui::SliderFloat2("Scale", scale, 0, 3);
1261  ImGui::SliderFloat2("Skew", skew, -3, 3);
1262  ImGui::SliderFloat4("Path XYWH", path_rect, -1000, 1000);
1263  ImGui::SliderFloat("Effect transform scale", &effect_transform_scale, 0,
1264  3);
1265  }
1266  ImGui::End();
1267 
1268  std::shared_ptr<Contents> input;
1269  Size input_size;
1270 
1271  auto input_rect =
1272  Rect::MakeXYWH(path_rect[0], path_rect[1], path_rect[2], path_rect[3]);
1273  auto texture = std::make_shared<TextureContents>();
1274  texture->SetSourceRect(Rect::MakeSize(boston->GetSize()));
1275  texture->SetDestinationRect(input_rect);
1276  texture->SetTexture(boston);
1277  texture->SetOpacity(input_color.alpha);
1278 
1279  input = texture;
1280  input_size = input_rect.GetSize();
1281 
1282  auto contents = FilterContents::MakeMorphology(
1283  FilterInput::Make(input), Radius{radius[0]}, Radius{radius[1]},
1284  morphology_types[selected_morphology_type]);
1285  contents->SetEffectTransform(Matrix::MakeScale(
1286  Vector2{effect_transform_scale, effect_transform_scale}));
1287 
1288  auto ctm = Matrix::MakeScale(GetContentScale()) *
1289  Matrix::MakeTranslation(Vector3(offset[0], offset[1])) *
1290  Matrix::MakeRotationZ(Radians(rotation)) *
1291  Matrix::MakeScale(Vector2(scale[0], scale[1])) *
1292  Matrix::MakeSkew(skew[0], skew[1]) *
1293  Matrix::MakeTranslation(-Point(input_size) / 2);
1294 
1295  Entity entity;
1296  entity.SetContents(contents);
1297  entity.SetTransform(ctm);
1298 
1299  entity.Render(context, pass);
1300 
1301  // Renders a red "cover" rectangle that shows the original position of the
1302  // unfiltered input.
1303  Entity cover_entity;
1304  cover_entity.SetContents(SolidColorContents::Make(
1305  PathBuilder{}.AddRect(input_rect).TakePath(), cover_color));
1306  cover_entity.SetTransform(ctm);
1307 
1308  cover_entity.Render(context, pass);
1309 
1310  // Renders a green bounding rect of the target filter.
1311  Entity bounds_entity;
1312  bounds_entity.SetContents(SolidColorContents::Make(
1313  PathBuilder{}.AddRect(contents->GetCoverage(entity).value()).TakePath(),
1314  bounds_color));
1315  bounds_entity.SetTransform(Matrix());
1316 
1317  bounds_entity.Render(context, pass);
1318 
1319  return true;
1320  };
1321  ASSERT_TRUE(OpenPlaygroundHere(callback));
1322 }

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(), offset, impeller::Entity::Render(), scale, impeller::Entity::SetContents(), impeller::Entity::SetTransform(), and impeller::PathBuilder::TakePath().

◆ TEST_P() [330/419]

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

Definition at line 2599 of file entity_unittests.cc.

2599  {
2600  std::vector<Point> points = {{10, 20}, {100, 200}};
2601  auto geometry = Geometry::MakePointField(points, 5.0, false);
2602  ASSERT_EQ(*geometry->GetCoverage(Matrix()), Rect::MakeLTRB(5, 15, 105, 205));
2603  ASSERT_EQ(*geometry->GetCoverage(Matrix::MakeTranslation({30, 0, 0})),
2604  Rect::MakeLTRB(35, 15, 135, 205));
2605 }

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

◆ TEST_P() [331/419]

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

Definition at line 2581 of file entity_unittests.cc.

2581  {
2582  // Square always gives 4 divisions.
2583  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(24.0, false), 4u);
2584  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(2.0, false), 4u);
2585  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(200.0, false), 4u);
2586 
2587  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(0.5, true), 4u);
2588  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(1.5, true), 8u);
2589  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(5.5, true), 24u);
2590  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(12.5, true), 34u);
2591  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(22.3, true), 22u);
2592  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(40.5, true), 40u);
2593  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(100.0, true), 100u);
2594  // Caps at 140.
2595  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(1000.0, true), 140u);
2596  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(20000.0, true), 140u);
2597 }

References impeller::PointFieldGeometry::ComputeCircleDivisions().

◆ TEST_P() [332/419]

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

Definition at line 2549 of file entity_unittests.cc.

2549  {
2550  RadialGradientContents contents;
2551  contents.SetColors({Color::CornflowerBlue()});
2552  ASSERT_TRUE(contents.IsOpaque());
2553  contents.SetColors({Color::CornflowerBlue().WithAlpha(0.5)});
2554  ASSERT_FALSE(contents.IsOpaque());
2555  contents.SetColors({Color::CornflowerBlue()});
2556  contents.SetTileMode(Entity::TileMode::kDecal);
2557  ASSERT_FALSE(contents.IsOpaque());
2558 }

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

◆ TEST_P() [333/419]

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

Definition at line 44 of file vertices_contents_unittests.cc.

44  {
45  using FS = GeometryColorPipeline::FragmentShader;
46 
47  auto contents = std::make_shared<VerticesContents>();
48  auto vertices = CreateColorVertices(
49  {{0, 0}, {100, 0}, {0, 100}, {100, 0}, {0, 100}, {100, 100}},
50  {Color::Red(), Color::Red(), Color::Red(), Color::Red(), Color::Red(),
51  Color::Red()});
52  auto src_contents = SolidColorContents::Make(
53  PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 100, 100)).TakePath(),
54  Color::Red());
55 
56  contents->SetGeometry(vertices);
57  contents->SetAlpha(0.5);
58  contents->SetBlendMode(BlendMode::kDestination);
59  contents->SetSourceContents(std::move(src_contents));
60 
61  auto content_context = GetContentContext();
62  auto buffer = content_context->GetContext()->CreateCommandBuffer();
63  auto render_target =
64  GetContentContext()->GetRenderTargetCache()->CreateOffscreenMSAA(
65  *content_context->GetContext(), {100, 100},
66  /*mip_count=*/1);
67  auto render_pass = buffer->CreateRenderPass(render_target);
68  auto recording_pass = std::make_shared<RecordingRenderPass>(
69  render_pass, GetContext(), render_target);
70  Entity entity;
71 
72  ASSERT_TRUE(recording_pass->GetCommands().empty());
73  ASSERT_TRUE(contents->Render(*content_context, entity, *recording_pass));
74 
75  ASSERT_TRUE(recording_pass->GetCommands().size() > 0);
76  const auto& cmd = recording_pass->GetCommands()[0];
77  auto* frag_uniforms = GetFragInfo<FS>(cmd);
78 
79  ASSERT_TRUE(frag_uniforms);
80  ASSERT_EQ(frag_uniforms->alpha, 0.5);
81 
82  if (GetParam() == PlaygroundBackend::kMetal) {
83  recording_pass->EncodeCommands();
84  }
85 }

References impeller::PathBuilder::AddRect(), CreateColorVertices(), impeller::kDestination, impeller::kMetal, impeller::SolidColorContents::Make(), impeller::TRect< Scalar >::MakeLTRB(), and impeller::Color::Red().

◆ TEST_P() [334/419]

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

Definition at line 1786 of file entity_unittests.cc.

1786  {
1787  auto callback = [&](ContentContext& context, RenderPass& pass) {
1788  static Color color = Color::Red();
1789  static float corner_radius = 100;
1790  static float blur_radius = 100;
1791  static bool show_coverage = false;
1792  static Color coverage_color = Color::Green().WithAlpha(0.2);
1793 
1794  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1795  ImGui::SliderFloat("Corner radius", &corner_radius, 0, 300);
1796  ImGui::SliderFloat("Blur radius", &blur_radius, 0, 300);
1797  ImGui::ColorEdit4("Color", reinterpret_cast<Scalar*>(&color));
1798  ImGui::Checkbox("Show coverage", &show_coverage);
1799  if (show_coverage) {
1800  ImGui::ColorEdit4("Coverage color",
1801  reinterpret_cast<Scalar*>(&coverage_color));
1802  }
1803  ImGui::End();
1804 
1805  static PlaygroundPoint top_left_point(Point(200, 200), 30, Color::White());
1806  static PlaygroundPoint bottom_right_point(Point(600, 400), 30,
1807  Color::White());
1808  auto [top_left, bottom_right] =
1809  DrawPlaygroundLine(top_left_point, bottom_right_point);
1810  auto rect =
1811  Rect::MakeLTRB(top_left.x, top_left.y, bottom_right.x, bottom_right.y);
1812 
1813  auto contents = std::make_unique<SolidRRectBlurContents>();
1814  contents->SetRRect(rect, {corner_radius, corner_radius});
1815  contents->SetColor(color);
1816  contents->SetSigma(Radius(blur_radius));
1817 
1818  Entity entity;
1819  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
1820  entity.SetContents(std::move(contents));
1821  entity.Render(context, pass);
1822 
1823  auto coverage = entity.GetCoverage();
1824  if (show_coverage && coverage.has_value()) {
1825  auto bounds_contents = std::make_unique<SolidColorContents>();
1826  bounds_contents->SetGeometry(Geometry::MakeFillPath(
1827  PathBuilder{}.AddRect(entity.GetCoverage().value()).TakePath()));
1828  bounds_contents->SetColor(coverage_color.Premultiply());
1829  Entity bounds_entity;
1830  bounds_entity.SetContents(std::move(bounds_contents));
1831  bounds_entity.Render(context, pass);
1832  }
1833 
1834  return true;
1835  };
1836  ASSERT_TRUE(OpenPlaygroundHere(callback));
1837 }

References impeller::PathBuilder::AddRect(), impeller::DrawPlaygroundLine(), impeller::Entity::GetCoverage(), impeller::Color::Green(), impeller::Geometry::MakeFillPath(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeScale(), impeller::Color::Premultiply(), impeller::Color::Red(), impeller::Entity::Render(), impeller::Entity::SetContents(), impeller::Entity::SetTransform(), impeller::PathBuilder::TakePath(), impeller::Color::White(), and impeller::Color::WithAlpha().

◆ TEST_P() [335/419]

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

Definition at line 2194 of file entity_unittests.cc.

2194  {
2195  auto runtime_stages =
2196  OpenAssetAsRuntimeStage("runtime_stage_example.frag.iplr");
2197  auto runtime_stage =
2198  runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
2199  ASSERT_TRUE(runtime_stage);
2200  ASSERT_TRUE(runtime_stage->IsDirty());
2201 
2202  bool expect_dirty = true;
2203  Pipeline<PipelineDescriptor>* first_pipeline;
2204  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
2205  EXPECT_EQ(runtime_stage->IsDirty(), expect_dirty);
2206 
2207  auto contents = std::make_shared<RuntimeEffectContents>();
2208  contents->SetGeometry(Geometry::MakeCover());
2209  contents->SetRuntimeStage(runtime_stage);
2210 
2211  struct FragUniforms {
2212  Vector2 iResolution;
2213  Scalar iTime;
2214  } frag_uniforms = {
2215  .iResolution = Vector2(GetWindowSize().width, GetWindowSize().height),
2216  .iTime = static_cast<Scalar>(GetSecondsElapsed()),
2217  };
2218  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
2219  uniform_data->resize(sizeof(FragUniforms));
2220  memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
2221  contents->SetUniformData(uniform_data);
2222 
2223  Entity entity;
2224  entity.SetContents(contents);
2225  bool result = contents->Render(context, entity, pass);
2226 
2227  if (expect_dirty) {
2228  EXPECT_NE(first_pipeline, pass.GetCommands().back().pipeline.get());
2229  first_pipeline = pass.GetCommands().back().pipeline.get();
2230  } else {
2231  EXPECT_EQ(pass.GetCommands().back().pipeline.get(), first_pipeline);
2232  }
2233 
2234  expect_dirty = false;
2235  return result;
2236  };
2237 
2238  // Simulate some renders and hot reloading of the shader.
2239  auto content_context = GetContentContext();
2240  {
2241  RenderTarget target =
2242  content_context->GetRenderTargetCache()->CreateOffscreen(
2243  *content_context->GetContext(), {1, 1}, 1u);
2244 
2245  testing::MockRenderPass mock_pass(GetContext(), target);
2246  callback(*content_context, mock_pass);
2247  callback(*content_context, mock_pass);
2248 
2249  // Dirty the runtime stage.
2250  runtime_stages = OpenAssetAsRuntimeStage("runtime_stage_example.frag.iplr");
2251  runtime_stage =
2252  runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
2253 
2254  ASSERT_TRUE(runtime_stage->IsDirty());
2255  expect_dirty = true;
2256 
2257  callback(*content_context, mock_pass);
2258  }
2259 }

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

◆ TEST_P() [336/419]

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

Definition at line 2261 of file entity_unittests.cc.

2261  {
2262  auto runtime_stages =
2263  OpenAssetAsRuntimeStage("runtime_stage_example.frag.iplr");
2264  auto runtime_stage =
2265  runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
2266  ASSERT_TRUE(runtime_stage);
2267  ASSERT_TRUE(runtime_stage->IsDirty());
2268 
2269  auto contents = std::make_shared<RuntimeEffectContents>();
2270  contents->SetGeometry(Geometry::MakeCover());
2271 
2272  contents->SetRuntimeStage(runtime_stage);
2273 
2274  struct FragUniforms {
2275  Vector2 iResolution;
2276  Scalar iTime;
2277  } frag_uniforms = {
2278  .iResolution = Vector2(GetWindowSize().width, GetWindowSize().height),
2279  .iTime = static_cast<Scalar>(GetSecondsElapsed()),
2280  };
2281  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
2282  uniform_data->resize(sizeof(FragUniforms));
2283  memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
2284  contents->SetUniformData(uniform_data);
2285 
2286  Entity entity;
2287  entity.SetContents(contents);
2288 
2289  // Create a render target with a depth-stencil, similar to how EntityPass
2290  // does.
2291  RenderTarget target =
2292  GetContentContext()->GetRenderTargetCache()->CreateOffscreenMSAA(
2293  *GetContext(), {GetWindowSize().width, GetWindowSize().height}, 1,
2294  "RuntimeEffect Texture");
2295  testing::MockRenderPass pass(GetContext(), target);
2296 
2297  ASSERT_TRUE(contents->Render(*GetContentContext(), entity, pass));
2298  ASSERT_EQ(pass.GetCommands().size(), 1u);
2299  const auto& command = pass.GetCommands()[0];
2300  ASSERT_TRUE(command.pipeline->GetDescriptor()
2301  .GetDepthStencilAttachmentDescriptor()
2302  .has_value());
2303  ASSERT_TRUE(command.pipeline->GetDescriptor()
2304  .GetFrontStencilAttachmentDescriptor()
2305  .has_value());
2306 }

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

◆ TEST_P() [337/419]

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

Definition at line 2308 of file entity_unittests.cc.

2308  {
2309  if (GetBackend() != PlaygroundBackend::kVulkan) {
2310  GTEST_SKIP() << "Test only applies to Vulkan";
2311  }
2312 
2313  auto runtime_stages =
2314  OpenAssetAsRuntimeStage("runtime_stage_example.frag.iplr");
2315  auto runtime_stage =
2316  runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
2317  ASSERT_TRUE(runtime_stage);
2318  ASSERT_TRUE(runtime_stage->IsDirty());
2319 
2320  auto contents = std::make_shared<RuntimeEffectContents>();
2321  contents->SetGeometry(Geometry::MakeCover());
2322  contents->SetRuntimeStage(runtime_stage);
2323 
2324  struct FragUniforms {
2325  Vector2 iResolution;
2326  Scalar iTime;
2327  } frag_uniforms = {
2328  .iResolution = Vector2(GetWindowSize().width, GetWindowSize().height),
2329  .iTime = static_cast<Scalar>(GetSecondsElapsed()),
2330  };
2331  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
2332  uniform_data->resize(sizeof(FragUniforms));
2333  memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
2334  contents->SetUniformData(uniform_data);
2335 
2336  Entity entity;
2337  entity.SetContents(contents);
2338 
2339  auto context = GetContentContext();
2340  RenderTarget target = context->GetRenderTargetCache()->CreateOffscreen(
2341  *context->GetContext(), {1, 1}, 1u);
2342 
2343  testing::MockRenderPass pass(GetContext(), target);
2344  ASSERT_TRUE(contents->Render(*context, entity, pass));
2345  ASSERT_EQ(pass.GetCommands().size(), 1u);
2346  const auto& command = pass.GetCommands()[0];
2347  ASSERT_EQ(command.fragment_bindings.buffers.size(), 1u);
2348  // 16 bytes:
2349  // 8 bytes for iResolution
2350  // 4 bytes for iTime
2351  // 4 bytes padding
2352  EXPECT_EQ(command.fragment_bindings.buffers[0].view.resource.range.length,
2353  16u);
2354 }

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

◆ TEST_P() [338/419]

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

Definition at line 1324 of file entity_unittests.cc.

1324  {
1325  Entity entity;
1326  ASSERT_EQ(entity.GetBlendMode(), BlendMode::kSourceOver);
1327  entity.SetBlendMode(BlendMode::kClear);
1328  ASSERT_EQ(entity.GetBlendMode(), BlendMode::kClear);
1329 }

References impeller::Entity::GetBlendMode(), impeller::kClear, impeller::kSourceOver, and impeller::Entity::SetBlendMode().

◆ TEST_P() [339/419]

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

Definition at line 2522 of file entity_unittests.cc.

2522  {
2523  SolidColorContents contents;
2524  contents.SetColor(Color::CornflowerBlue());
2525  ASSERT_TRUE(contents.IsOpaque());
2526  contents.SetColor(Color::CornflowerBlue().WithAlpha(0.5));
2527  ASSERT_FALSE(contents.IsOpaque());
2528 }

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

◆ TEST_P() [340/419]

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

Definition at line 841 of file entity_unittests.cc.

841  {
842  {
843  auto geometry = Geometry::MakeStrokePath(Path{});
844  auto path_geometry = static_cast<StrokePathGeometry*>(geometry.get());
845  ASSERT_FLOAT_EQ(path_geometry->GetMiterLimit(), 4);
846  }
847 
848  {
849  auto geometry = Geometry::MakeStrokePath(Path{}, 1.0, /*miter_limit=*/8.0);
850  auto path_geometry = static_cast<StrokePathGeometry*>(geometry.get());
851  ASSERT_FLOAT_EQ(path_geometry->GetMiterLimit(), 8);
852  }
853 
854  {
855  auto geometry = Geometry::MakeStrokePath(Path{}, 1.0, /*miter_limit=*/-1.0);
856  auto path_geometry = static_cast<StrokePathGeometry*>(geometry.get());
857  ASSERT_FLOAT_EQ(path_geometry->GetMiterLimit(), 4);
858  }
859 }

References impeller::Geometry::MakeStrokePath().

◆ TEST_P() [341/419]

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

Definition at line 819 of file entity_unittests.cc.

819  {
820  {
821  auto geometry = Geometry::MakeStrokePath(Path{});
822  auto path_geometry = static_cast<StrokePathGeometry*>(geometry.get());
823  // Defaults.
824  ASSERT_EQ(path_geometry->GetStrokeCap(), Cap::kButt);
825  ASSERT_EQ(path_geometry->GetStrokeJoin(), Join::kMiter);
826  }
827 
828  {
829  auto geometry = Geometry::MakeStrokePath(Path{}, 1.0, 4.0, Cap::kSquare);
830  auto path_geometry = static_cast<StrokePathGeometry*>(geometry.get());
831  ASSERT_EQ(path_geometry->GetStrokeCap(), Cap::kSquare);
832  }
833 
834  {
835  auto geometry = Geometry::MakeStrokePath(Path{}, 1.0, 4.0, Cap::kRound);
836  auto path_geometry = static_cast<StrokePathGeometry*>(geometry.get());
837  ASSERT_EQ(path_geometry->GetStrokeCap(), Cap::kRound);
838  }
839 }

References impeller::kButt, impeller::kMiter, impeller::kRound, impeller::kSquare, and impeller::Geometry::MakeStrokePath().

◆ TEST_P() [342/419]

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

Definition at line 1613 of file entity_unittests.cc.

1613  {
1614  // No transform
1615  {
1616  auto fill = std::make_shared<SolidColorContents>();
1617  fill->SetColor(Color::CornflowerBlue());
1618  auto expected = Rect::MakeLTRB(100, 110, 200, 220);
1619  fill->SetGeometry(
1620  Geometry::MakeFillPath(PathBuilder{}.AddRect(expected).TakePath()));
1621 
1622  auto coverage = fill->GetCoverage({});
1623  ASSERT_TRUE(coverage.has_value());
1624  ASSERT_RECT_NEAR(coverage.value(), expected);
1625  }
1626 
1627  // Entity transform
1628  {
1629  auto fill = std::make_shared<SolidColorContents>();
1630  fill->SetColor(Color::CornflowerBlue());
1631  fill->SetGeometry(Geometry::MakeFillPath(
1632  PathBuilder{}.AddRect(Rect::MakeLTRB(100, 110, 200, 220)).TakePath()));
1633 
1634  Entity entity;
1635  entity.SetTransform(Matrix::MakeTranslation(Vector2(4, 5)));
1636  entity.SetContents(std::move(fill));
1637 
1638  auto coverage = entity.GetCoverage();
1639  auto expected = Rect::MakeLTRB(104, 115, 204, 225);
1640  ASSERT_TRUE(coverage.has_value());
1641  ASSERT_RECT_NEAR(coverage.value(), expected);
1642  }
1643 
1644  // No coverage for fully transparent colors
1645  {
1646  auto fill = std::make_shared<SolidColorContents>();
1647  fill->SetColor(Color::WhiteTransparent());
1648  fill->SetGeometry(Geometry::MakeFillPath(
1649  PathBuilder{}.AddRect(Rect::MakeLTRB(100, 110, 200, 220)).TakePath()));
1650 
1651  auto coverage = fill->GetCoverage({});
1652  ASSERT_FALSE(coverage.has_value());
1653  }
1654 }

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::SetTransform(), and impeller::Color::WhiteTransparent().

◆ TEST_P() [343/419]

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

Definition at line 1656 of file entity_unittests.cc.

1656  {
1657  // No path.
1658  {
1659  auto fill = std::make_shared<SolidColorContents>();
1660  fill->SetColor(Color::CornflowerBlue());
1661  ASSERT_FALSE(fill->ShouldRender(Entity{}, Rect::MakeSize(Size{100, 100})));
1662  ASSERT_FALSE(
1663  fill->ShouldRender(Entity{}, Rect::MakeLTRB(-100, -100, -50, -50)));
1664  }
1665 
1666  // With path.
1667  {
1668  auto fill = std::make_shared<SolidColorContents>();
1669  fill->SetColor(Color::CornflowerBlue());
1670  fill->SetGeometry(Geometry::MakeFillPath(
1671  PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 100, 100)).TakePath()));
1672  ASSERT_TRUE(fill->ShouldRender(Entity{}, Rect::MakeSize(Size{100, 100})));
1673  ASSERT_FALSE(
1674  fill->ShouldRender(Entity{}, Rect::MakeLTRB(-100, -100, -50, -50)));
1675  }
1676 
1677  // With paint cover.
1678  {
1679  auto fill = std::make_shared<SolidColorContents>();
1680  fill->SetColor(Color::CornflowerBlue());
1681  fill->SetGeometry(Geometry::MakeCover());
1682  ASSERT_TRUE(fill->ShouldRender(Entity{}, Rect::MakeSize(Size{100, 100})));
1683  ASSERT_TRUE(
1684  fill->ShouldRender(Entity{}, Rect::MakeLTRB(-100, -100, -50, -50)));
1685  }
1686 }

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

◆ TEST_P() [344/419]

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

Definition at line 1337 of file entity_unittests.cc.

1337  {
1338  {
1339  auto geometry = Geometry::MakeStrokePath(
1340  PathBuilder{}.AddLine({0, 0}, {10, 10}).TakePath(), 4.0, 4.0,
1341  Cap::kButt, Join::kBevel);
1342 
1343  Entity entity;
1344  auto contents = std::make_unique<SolidColorContents>();
1345  contents->SetGeometry(std::move(geometry));
1346  contents->SetColor(Color::Black());
1347  entity.SetContents(std::move(contents));
1348  auto actual = entity.GetCoverage();
1349  auto expected = Rect::MakeLTRB(-2, -2, 12, 12);
1350  ASSERT_TRUE(actual.has_value());
1351  ASSERT_RECT_NEAR(actual.value(), expected);
1352  }
1353 
1354  // Cover the Cap::kSquare case.
1355  {
1356  auto geometry = Geometry::MakeStrokePath(
1357  PathBuilder{}.AddLine({0, 0}, {10, 10}).TakePath(), 4.0, 4.0,
1358  Cap::kSquare, Join::kBevel);
1359 
1360  Entity entity;
1361  auto contents = std::make_unique<SolidColorContents>();
1362  contents->SetGeometry(std::move(geometry));
1363  contents->SetColor(Color::Black());
1364  entity.SetContents(std::move(contents));
1365  auto actual = entity.GetCoverage();
1366  auto expected =
1367  Rect::MakeLTRB(-sqrt(8), -sqrt(8), 10 + sqrt(8), 10 + sqrt(8));
1368  ASSERT_TRUE(actual.has_value());
1369  ASSERT_RECT_NEAR(actual.value(), expected);
1370  }
1371 
1372  // Cover the Join::kMiter case.
1373  {
1374  auto geometry = Geometry::MakeStrokePath(
1375  PathBuilder{}.AddLine({0, 0}, {10, 10}).TakePath(), 4.0, 2.0,
1376  Cap::kSquare, Join::kMiter);
1377 
1378  Entity entity;
1379  auto contents = std::make_unique<SolidColorContents>();
1380  contents->SetGeometry(std::move(geometry));
1381  contents->SetColor(Color::Black());
1382  entity.SetContents(std::move(contents));
1383  auto actual = entity.GetCoverage();
1384  auto expected = Rect::MakeLTRB(-4, -4, 14, 14);
1385  ASSERT_TRUE(actual.has_value());
1386  ASSERT_RECT_NEAR(actual.value(), expected);
1387  }
1388 }

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

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

Definition at line 2684 of file entity_unittests.cc.

2684  {
2685  auto content_context = GetContentContext();
2686 
2687  auto default_color_burn = content_context->GetBlendColorBurnPipeline({
2688  .color_attachment_pixel_format = PixelFormat::kR8G8B8A8UNormInt,
2689  .has_depth_stencil_attachments = false,
2690  });
2691  auto alt_color_burn = content_context->GetBlendColorBurnPipeline(
2692  {.color_attachment_pixel_format = PixelFormat::kR8G8B8A8UNormInt,
2693  .has_depth_stencil_attachments = true});
2694 
2695  ASSERT_NE(default_color_burn, alt_color_burn);
2696  ASSERT_EQ(default_color_burn->GetDescriptor().GetSpecializationConstants(),
2697  alt_color_burn->GetDescriptor().GetSpecializationConstants());
2698 
2699  auto decal_supported = static_cast<Scalar>(
2700  GetContext()->GetCapabilities()->SupportsDecalSamplerAddressMode());
2701  std::vector<Scalar> expected_constants = {5, decal_supported};
2702  ASSERT_EQ(default_color_burn->GetDescriptor().GetSpecializationConstants(),
2703  expected_constants);
2704 }

References impeller::kR8G8B8A8UNormInt.

◆ TEST_P() [346/419]

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

Definition at line 1999 of file entity_unittests.cc.

1999  {
2000  auto image = CreateTextureForFixture("embarcadero.jpg");
2001  ASSERT_TRUE(image);
2002 
2003  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
2004  auto filtered =
2005  ColorFilterContents::MakeSrgbToLinearFilter(FilterInput::Make(image));
2006 
2007  // Define the entity that will serve as the control image as a Gaussian blur
2008  // filter with no filter at all.
2009  Entity entity_left;
2010  entity_left.SetTransform(Matrix::MakeScale(GetContentScale()) *
2011  Matrix::MakeTranslation({100, 300}) *
2012  Matrix::MakeScale(Vector2{0.5, 0.5}));
2013  auto unfiltered = FilterContents::MakeGaussianBlur(FilterInput::Make(image),
2014  Sigma{0}, Sigma{0});
2015  entity_left.SetContents(unfiltered);
2016 
2017  // Define the entity that will be filtered from sRGB to linear.
2018  Entity entity_right;
2019  entity_right.SetTransform(Matrix::MakeScale(GetContentScale()) *
2020  Matrix::MakeTranslation({500, 300}) *
2021  Matrix::MakeScale(Vector2{0.5, 0.5}));
2022  entity_right.SetContents(filtered);
2023  return entity_left.Render(context, pass) &&
2024  entity_right.Render(context, pass);
2025  };
2026 
2027  ASSERT_TRUE(OpenPlaygroundHere(callback));
2028 }

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::SetTransform().

◆ TEST_P() [347/419]

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

Definition at line 1978 of file entity_unittests.cc.

1978  {
1979  // Set up a simple color background.
1980  auto fill = std::make_shared<SolidColorContents>();
1981  fill->SetGeometry(Geometry::MakeFillPath(
1982  PathBuilder{}.AddRect(Rect::MakeXYWH(0, 0, 300, 400)).TakePath()));
1983  fill->SetColor(Color::DeepPink());
1984 
1985  auto filter =
1986  ColorFilterContents::MakeSrgbToLinearFilter(FilterInput::Make(fill));
1987 
1988  Entity e;
1989  e.SetTransform(Matrix());
1990 
1991  // Confirm that the actual filter coverage matches the expected coverage.
1992  auto actual = filter->GetCoverage(e);
1993  auto expected = Rect::MakeXYWH(0, 0, 300, 400);
1994 
1995  ASSERT_TRUE(actual.has_value());
1996  ASSERT_RECT_NEAR(actual.value(), expected);
1997 }

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::SetTransform().

◆ TEST_P() [348/419]

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

Definition at line 383 of file entity_unittests.cc.

383  {
384  const Point padding(300, 250);
385  const Point margin(140, 180);
386 
387  auto callback = [&](ContentContext& context, RenderPass& pass) {
388  // Slightly above sqrt(2) by default, so that right angles are just below
389  // the limit and acute angles are over the limit (causing them to get
390  // beveled).
391  static Scalar miter_limit = 1.41421357;
392  static Scalar width = 30;
393 
394  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
395  {
396  ImGui::SliderFloat("Miter limit", &miter_limit, 0, 30);
397  ImGui::SliderFloat("Stroke width", &width, 0, 100);
398  if (ImGui::Button("Reset")) {
399  miter_limit = 1.41421357;
400  width = 30;
401  }
402  }
403  ImGui::End();
404 
405  auto world_matrix = Matrix::MakeScale(GetContentScale());
406  auto render_path = [width = width, &context, &pass, &world_matrix](
407  const Path& path, Cap cap, Join join) {
408  auto contents = std::make_unique<SolidColorContents>();
409  contents->SetGeometry(
410  Geometry::MakeStrokePath(path, width, miter_limit, cap, join));
411  contents->SetColor(Color::Red());
412 
413  Entity entity;
414  entity.SetTransform(world_matrix);
415  entity.SetContents(std::move(contents));
416 
417  auto coverage = entity.GetCoverage();
418  if (coverage.has_value()) {
419  auto bounds_contents = std::make_unique<SolidColorContents>();
420  bounds_contents->SetGeometry(Geometry::MakeFillPath(
421  PathBuilder{}.AddRect(entity.GetCoverage().value()).TakePath()));
422  bounds_contents->SetColor(Color::Green().WithAlpha(0.5));
423  Entity bounds_entity;
424  bounds_entity.SetContents(std::move(bounds_contents));
425  bounds_entity.Render(context, pass);
426  }
427 
428  entity.Render(context, pass);
429  };
430 
431  const Point a_def(0, 0), b_def(0, 100), c_def(150, 0), d_def(150, -100),
432  e_def(75, 75);
433  const Scalar r = 30;
434  // Cap::kButt demo.
435  {
436  Point off = Point(0, 0) * padding + margin;
437  static PlaygroundPoint point_a(off + a_def, r, Color::Black());
438  static PlaygroundPoint point_b(off + b_def, r, Color::White());
439  auto [a, b] = DrawPlaygroundLine(point_a, point_b);
440  static PlaygroundPoint point_c(off + c_def, r, Color::Black());
441  static PlaygroundPoint point_d(off + d_def, r, Color::White());
442  auto [c, d] = DrawPlaygroundLine(point_c, point_d);
443  render_path(PathBuilder{}.AddCubicCurve(a, b, d, c).TakePath(),
444  Cap::kButt, Join::kBevel);
445  }
446 
447  // Cap::kSquare demo.
448  {
449  Point off = Point(1, 0) * padding + margin;
450  static PlaygroundPoint point_a(off + a_def, r, Color::Black());
451  static PlaygroundPoint point_b(off + b_def, r, Color::White());
452  auto [a, b] = DrawPlaygroundLine(point_a, point_b);
453  static PlaygroundPoint point_c(off + c_def, r, Color::Black());
454  static PlaygroundPoint point_d(off + d_def, r, Color::White());
455  auto [c, d] = DrawPlaygroundLine(point_c, point_d);
456  render_path(PathBuilder{}.AddCubicCurve(a, b, d, c).TakePath(),
457  Cap::kSquare, Join::kBevel);
458  }
459 
460  // Cap::kRound demo.
461  {
462  Point off = Point(2, 0) * padding + margin;
463  static PlaygroundPoint point_a(off + a_def, r, Color::Black());
464  static PlaygroundPoint point_b(off + b_def, r, Color::White());
465  auto [a, b] = DrawPlaygroundLine(point_a, point_b);
466  static PlaygroundPoint point_c(off + c_def, r, Color::Black());
467  static PlaygroundPoint point_d(off + d_def, r, Color::White());
468  auto [c, d] = DrawPlaygroundLine(point_c, point_d);
469  render_path(PathBuilder{}.AddCubicCurve(a, b, d, c).TakePath(),
470  Cap::kRound, Join::kBevel);
471  }
472 
473  // Join::kBevel demo.
474  {
475  Point off = Point(0, 1) * padding + margin;
476  static PlaygroundPoint point_a =
477  PlaygroundPoint(off + a_def, r, Color::White());
478  static PlaygroundPoint point_b =
479  PlaygroundPoint(off + e_def, r, Color::White());
480  static PlaygroundPoint point_c =
481  PlaygroundPoint(off + c_def, r, Color::White());
482  Point a = DrawPlaygroundPoint(point_a);
483  Point b = DrawPlaygroundPoint(point_b);
484  Point c = DrawPlaygroundPoint(point_c);
485  render_path(
486  PathBuilder{}.MoveTo(a).LineTo(b).LineTo(c).Close().TakePath(),
487  Cap::kButt, Join::kBevel);
488  }
489 
490  // Join::kMiter demo.
491  {
492  Point off = Point(1, 1) * padding + margin;
493  static PlaygroundPoint point_a(off + a_def, r, Color::White());
494  static PlaygroundPoint point_b(off + e_def, r, Color::White());
495  static PlaygroundPoint point_c(off + c_def, r, Color::White());
496  Point a = DrawPlaygroundPoint(point_a);
497  Point b = DrawPlaygroundPoint(point_b);
498  Point c = DrawPlaygroundPoint(point_c);
499  render_path(
500  PathBuilder{}.MoveTo(a).LineTo(b).LineTo(c).Close().TakePath(),
501  Cap::kButt, Join::kMiter);
502  }
503 
504  // Join::kRound demo.
505  {
506  Point off = Point(2, 1) * padding + margin;
507  static PlaygroundPoint point_a(off + a_def, r, Color::White());
508  static PlaygroundPoint point_b(off + e_def, r, Color::White());
509  static PlaygroundPoint point_c(off + c_def, r, Color::White());
510  Point a = DrawPlaygroundPoint(point_a);
511  Point b = DrawPlaygroundPoint(point_b);
512  Point c = DrawPlaygroundPoint(point_c);
513  render_path(
514  PathBuilder{}.MoveTo(a).LineTo(b).LineTo(c).Close().TakePath(),
515  Cap::kButt, Join::kRound);
516  }
517 
518  return true;
519  };
520  ASSERT_TRUE(OpenPlaygroundHere(callback));
521 }

References impeller::PathBuilder::AddCubicCurve(), impeller::PathBuilder::AddRect(), impeller::saturated::b, impeller::Color::Black(), impeller::Close(), impeller::DrawPlaygroundLine(), impeller::DrawPlaygroundPoint(), impeller::Entity::GetCoverage(), impeller::Color::Green(), 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::SetTransform(), impeller::PathBuilder::TakePath(), and impeller::Color::White().

◆ TEST_P() [349/419]

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

Definition at line 319 of file entity_unittests.cc.

319  {
320  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
321  Path path = PathBuilder{}
322  .MoveTo({100, 100})
323  .LineTo({100, 200})
324  .MoveTo({100, 300})
325  .LineTo({100, 400})
326  .MoveTo({100, 500})
327  .LineTo({100, 600})
328  .TakePath();
329 
330  Entity entity;
331  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
332  auto contents = std::make_unique<TiledTextureContents>();
333  contents->SetGeometry(Geometry::MakeStrokePath(path, 100.0));
334  contents->SetTexture(bridge);
335  contents->SetTileModes(Entity::TileMode::kClamp, Entity::TileMode::kClamp);
336  entity.SetContents(std::move(contents));
337  ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
338 }

References impeller::Entity::kClamp, impeller::LineTo(), impeller::Matrix::MakeScale(), impeller::Geometry::MakeStrokePath(), impeller::MoveTo(), impeller::PathBuilder::MoveTo(), impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [350/419]

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

Definition at line 2560 of file entity_unittests.cc.

2560  {
2561  RadialGradientContents contents;
2562  contents.SetColors({Color::CornflowerBlue()});
2563  ASSERT_TRUE(contents.IsOpaque());
2564  contents.SetColors({Color::CornflowerBlue().WithAlpha(0.5)});
2565  ASSERT_FALSE(contents.IsOpaque());
2566  contents.SetColors({Color::CornflowerBlue()});
2567  contents.SetTileMode(Entity::TileMode::kDecal);
2568  ASSERT_FALSE(contents.IsOpaque());
2569 }

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

◆ TEST_P() [351/419]

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

Definition at line 2627 of file entity_unittests.cc.

2627  {
2628  ASSERT_EQ(TextFrame::RoundScaledFontSize(0.4321111f, 12), 0.43f);
2629  ASSERT_EQ(TextFrame::RoundScaledFontSize(0.5321111f, 12), 0.53f);
2630  ASSERT_EQ(TextFrame::RoundScaledFontSize(2.1f, 12), 2.1f);
2631  ASSERT_EQ(TextFrame::RoundScaledFontSize(0.0f, 12), 0.0f);
2632 }

References impeller::TextFrame::RoundScaledFontSize().

◆ TEST_P() [352/419]

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

Definition at line 300 of file entity_unittests.cc.

300  {
301  Path path = PathBuilder{}
302  .MoveTo({100, 100})
303  .LineTo({100, 200})
304  .MoveTo({100, 300})
305  .LineTo({100, 400})
306  .MoveTo({100, 500})
307  .LineTo({100, 600})
308  .TakePath();
309 
310  Entity entity;
311  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
312  auto contents = std::make_unique<SolidColorContents>();
313  contents->SetGeometry(Geometry::MakeStrokePath(path, 5.0));
314  contents->SetColor(Color::Red());
315  entity.SetContents(std::move(contents));
316  ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
317 }

References impeller::LineTo(), impeller::Matrix::MakeScale(), impeller::Geometry::MakeStrokePath(), impeller::MoveTo(), impeller::PathBuilder::MoveTo(), impeller::Color::Red(), impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [353/419]

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

Definition at line 2571 of file entity_unittests.cc.

2571  {
2572  auto bay_bridge = CreateTextureForFixture("bay_bridge.jpg");
2573  TiledTextureContents contents;
2574  contents.SetTexture(bay_bridge);
2575  // This is a placeholder test. Images currently never decompress as opaque
2576  // (whether in Flutter or the playground), and so this should currently always
2577  // return false in practice.
2578  ASSERT_FALSE(contents.IsOpaque());
2579 }

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

◆ TEST_P() [354/419]

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

Definition at line 20 of file tiled_texture_contents_unittests.cc.

20  {
21  TextureDescriptor texture_desc;
22  texture_desc.size = {100, 100};
23  texture_desc.type = TextureType::kTexture2D;
24  texture_desc.format = PixelFormat::kR8G8B8A8UNormInt;
25  texture_desc.storage_mode = StorageMode::kDevicePrivate;
26  auto texture =
27  GetContext()->GetResourceAllocator()->CreateTexture(texture_desc);
28 
29  TiledTextureContents contents;
30  contents.SetTexture(texture);
31  contents.SetGeometry(Geometry::MakeCover());
32 
33  auto content_context = GetContentContext();
34  auto buffer = content_context->GetContext()->CreateCommandBuffer();
35  auto render_target =
36  GetContentContext()->GetRenderTargetCache()->CreateOffscreenMSAA(
37  *content_context->GetContext(), {100, 100},
38  /*mip_count=*/1);
39  auto render_pass = buffer->CreateRenderPass(render_target);
40  auto recording_pass = std::make_shared<RecordingRenderPass>(
41  render_pass, GetContext(), render_target);
42 
43  ASSERT_TRUE(contents.Render(*GetContentContext(), {}, *recording_pass));
44  const std::vector<Command>& commands = recording_pass->GetCommands();
45 
46  ASSERT_EQ(commands.size(), 1u);
47  EXPECT_TRUE(commands[0].pipeline->GetDescriptor().GetLabel().find(
48  "TextureFill Pipeline") != std::string::npos);
49 
50  if (GetParam() == PlaygroundBackend::kMetal) {
51  recording_pass->EncodeCommands();
52  }
53 }

References impeller::TextureDescriptor::format, impeller::kDevicePrivate, impeller::kMetal, impeller::kR8G8B8A8UNormInt, impeller::kTexture2D, impeller::Geometry::MakeCover(), impeller::TiledTextureContents::Render(), impeller::ColorSourceContents::SetGeometry(), impeller::TiledTextureContents::SetTexture(), impeller::TextureDescriptor::size, impeller::TextureDescriptor::storage_mode, and impeller::TextureDescriptor::type.

◆ TEST_P() [355/419]

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

Definition at line 57 of file tiled_texture_contents_unittests.cc.

57  {
58  if (GetParam() != PlaygroundBackend::kOpenGLES) {
59  GTEST_SKIP_(
60  "External OES textures are only valid for the OpenGLES backend.");
61  }
62 
63  TextureDescriptor texture_desc;
64  texture_desc.size = {100, 100};
65  texture_desc.type = TextureType::kTextureExternalOES;
66  texture_desc.format = PixelFormat::kR8G8B8A8UNormInt;
67  texture_desc.storage_mode = StorageMode::kDevicePrivate;
68  auto texture =
69  GetContext()->GetResourceAllocator()->CreateTexture(texture_desc);
70 
71  TiledTextureContents contents;
72  contents.SetTexture(texture);
73  contents.SetGeometry(Geometry::MakeCover());
74 
75  auto content_context = GetContentContext();
76  auto buffer = content_context->GetContext()->CreateCommandBuffer();
77  auto render_target =
78  GetContentContext()->GetRenderTargetCache()->CreateOffscreenMSAA(
79  *content_context->GetContext(), {100, 100},
80  /*mip_count=*/1);
81  auto render_pass = buffer->CreateRenderPass(render_target);
82 
83  ASSERT_TRUE(contents.Render(*GetContentContext(), {}, *render_pass));
84  const std::vector<Command>& commands = render_pass->GetCommands();
85 
86  ASSERT_EQ(commands.size(), 1u);
87  EXPECT_TRUE(commands[0].pipeline->GetDescriptor().GetLabel().find(
88  "TiledTextureFillExternal Pipeline") != std::string::npos);
89 }

References impeller::TextureDescriptor::format, impeller::kDevicePrivate, impeller::kOpenGLES, impeller::kR8G8B8A8UNormInt, impeller::kTextureExternalOES, impeller::Geometry::MakeCover(), impeller::TiledTextureContents::Render(), impeller::ColorSourceContents::SetGeometry(), impeller::TiledTextureContents::SetTexture(), impeller::TextureDescriptor::size, impeller::TextureDescriptor::storage_mode, and impeller::TextureDescriptor::type.

◆ TEST_P() [356/419]

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

Definition at line 340 of file entity_unittests.cc.

340  {
341  auto callback = [&](ContentContext& context, RenderPass& pass) {
342  Point offset(100, 100);
343 
344  static PlaygroundPoint point_a(Point(10, 10) + offset, 20, Color::White());
345  Point a = DrawPlaygroundPoint(point_a);
346  static PlaygroundPoint point_b(Point(210, 10) + offset, 20, Color::White());
347  Point b = DrawPlaygroundPoint(point_b);
348  static PlaygroundPoint point_c(Point(210, 210) + offset, 20,
349  Color::White());
350  Point c = DrawPlaygroundPoint(point_c);
351  static PlaygroundPoint point_d(Point(10, 210) + offset, 20, Color::White());
352  Point d = DrawPlaygroundPoint(point_d);
353  static PlaygroundPoint point_e(Point(50, 50) + offset, 20, Color::White());
354  Point e = DrawPlaygroundPoint(point_e);
355  static PlaygroundPoint point_f(Point(100, 50) + offset, 20, Color::White());
356  Point f = DrawPlaygroundPoint(point_f);
357  static PlaygroundPoint point_g(Point(50, 150) + offset, 20, Color::White());
358  Point g = DrawPlaygroundPoint(point_g);
359  Path path = PathBuilder{}
360  .MoveTo(a)
361  .LineTo(b)
362  .LineTo(c)
363  .LineTo(d)
364  .Close()
365  .MoveTo(e)
366  .LineTo(f)
367  .LineTo(g)
368  .Close()
369  .TakePath();
370 
371  Entity entity;
372  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
373  auto contents = std::make_unique<SolidColorContents>();
374  contents->SetGeometry(Geometry::MakeStrokePath(path, 20.0));
375  contents->SetColor(Color::Red());
376  entity.SetContents(std::move(contents));
377 
378  return entity.Render(context, pass);
379  };
380  ASSERT_TRUE(OpenPlaygroundHere(callback));
381 }

References impeller::saturated::b, impeller::PathBuilder::Close(), impeller::DrawPlaygroundPoint(), impeller::PathBuilder::LineTo(), impeller::Matrix::MakeScale(), impeller::Geometry::MakeStrokePath(), impeller::PathBuilder::MoveTo(), offset, impeller::Color::Red(), impeller::Entity::Render(), impeller::Entity::SetContents(), impeller::Entity::SetTransform(), impeller::PathBuilder::TakePath(), and impeller::Color::White().

◆ TEST_P() [357/419]

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

Definition at line 2161 of file entity_unittests.cc.

2161  {
2162  if (GetParam() == PlaygroundBackend::kOpenGLES) {
2163  // TODO(114588) : Support YUV to RGB filter on OpenGLES backend.
2164  GTEST_SKIP_("YUV to RGB filter is not supported on OpenGLES backend yet.");
2165  }
2166 
2167  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
2168  YUVColorSpace yuv_color_space_array[2]{YUVColorSpace::kBT601FullRange,
2169  YUVColorSpace::kBT601LimitedRange};
2170  for (int i = 0; i < 2; i++) {
2171  auto yuv_color_space = yuv_color_space_array[i];
2172  auto textures =
2173  CreateTestYUVTextures(GetContext().get(), yuv_color_space);
2174  auto filter_contents = FilterContents::MakeYUVToRGBFilter(
2175  textures[0], textures[1], yuv_color_space);
2176  Entity filter_entity;
2177  filter_entity.SetContents(filter_contents);
2178  auto snapshot = filter_contents->RenderToSnapshot(context, filter_entity);
2179 
2180  Entity entity;
2181  auto contents = TextureContents::MakeRect(Rect::MakeLTRB(0, 0, 256, 256));
2182  contents->SetTexture(snapshot->texture);
2183  contents->SetSourceRect(Rect::MakeSize(snapshot->texture->GetSize()));
2184  entity.SetContents(contents);
2185  entity.SetTransform(
2186  Matrix::MakeTranslation({static_cast<Scalar>(100 + 400 * i), 300}));
2187  entity.Render(context, pass);
2188  }
2189  return true;
2190  };
2191  ASSERT_TRUE(OpenPlaygroundHere(callback));
2192 }

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(), impeller::Entity::SetTransform(), and textures.

◆ TEST_P() [358/419]

impeller::testing::TEST_P ( GaussianBlurFilterContentsTest  ,
CalculateUVsSimple   
)

Definition at line 309 of file gaussian_blur_filter_contents_unittests.cc.

309  {
310  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
311  auto filter_input = FilterInput::Make(texture);
312  Entity entity;
313  Quad uvs = GaussianBlurFilterContents::CalculateUVs(
314  filter_input, entity, Rect::MakeSize(ISize(100, 100)), ISize(100, 100));
315  std::optional<Rect> uvs_bounds = Rect::MakePointBounds(uvs);
316  EXPECT_TRUE(uvs_bounds.has_value());
317  if (uvs_bounds.has_value()) {
318  EXPECT_TRUE(RectNear(uvs_bounds.value(), Rect::MakeXYWH(0, 0, 1, 1)));
319  }
320 }

References impeller::GaussianBlurFilterContents::CalculateUVs(), impeller::FilterInput::Make(), impeller::TRect< Scalar >::MakePointBounds(), impeller::TRect< Scalar >::MakeSize(), impeller::TRect< Scalar >::MakeXYWH(), and RectNear().

◆ TEST_P() [359/419]

impeller::testing::TEST_P ( GaussianBlurFilterContentsTest  ,
CoverageWithEffectTransform   
)

Definition at line 161 of file gaussian_blur_filter_contents_unittests.cc.

161  {
162  Matrix effect_transform = Matrix::MakeScale({2.0, 2.0, 1.0});
163  fml::StatusOr<Scalar> sigma_radius_1 =
164  CalculateSigmaForBlurRadius(1.0, effect_transform);
165  ASSERT_TRUE(sigma_radius_1.ok());
166  GaussianBlurFilterContents contents(
167  /*sigma_x=*/sigma_radius_1.value(),
168  /*sigma_y=*/sigma_radius_1.value(), Entity::TileMode::kDecal,
169  FilterContents::BlurStyle::kNormal, /*mask_geometry=*/nullptr);
170  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
171  FilterInput::Vector inputs = {FilterInput::Make(texture)};
172  Entity entity;
173  entity.SetTransform(Matrix::MakeTranslation({100, 100, 0}));
174  std::optional<Rect> coverage =
175  contents.GetFilterCoverage(inputs, entity, effect_transform);
176  EXPECT_TRUE(coverage.has_value());
177  if (coverage.has_value()) {
178  EXPECT_RECT_NEAR(coverage.value(),
179  Rect::MakeLTRB(100 - 1, 100 - 1, 200 + 1, 200 + 1));
180  }
181 }

References EXPECT_RECT_NEAR, impeller::GaussianBlurFilterContents::GetFilterCoverage(), impeller::Entity::kDecal, impeller::FilterContents::kNormal, impeller::FilterInput::Make(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), and impeller::Entity::SetTransform().

◆ TEST_P() [360/419]

impeller::testing::TEST_P ( GaussianBlurFilterContentsTest  ,
CoverageWithTexture   
)

Definition at line 140 of file gaussian_blur_filter_contents_unittests.cc.

140  {
141  fml::StatusOr<Scalar> sigma_radius_1 =
142  CalculateSigmaForBlurRadius(1.0, Matrix());
143  ASSERT_TRUE(sigma_radius_1.ok());
144  GaussianBlurFilterContents contents(
145  /*sigma_X=*/sigma_radius_1.value(),
146  /*sigma_y=*/sigma_radius_1.value(), Entity::TileMode::kDecal,
147  FilterContents::BlurStyle::kNormal, /*mask_geometry=*/nullptr);
148  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
149  FilterInput::Vector inputs = {FilterInput::Make(texture)};
150  Entity entity;
151  entity.SetTransform(Matrix::MakeTranslation({100, 100, 0}));
152  std::optional<Rect> coverage =
153  contents.GetFilterCoverage(inputs, entity, /*effect_transform=*/Matrix());
154 
155  EXPECT_TRUE(coverage.has_value());
156  if (coverage.has_value()) {
157  EXPECT_RECT_NEAR(coverage.value(), Rect::MakeLTRB(99, 99, 201, 201));
158  }
159 }

References EXPECT_RECT_NEAR, impeller::GaussianBlurFilterContents::GetFilterCoverage(), impeller::Entity::kDecal, impeller::FilterContents::kNormal, impeller::FilterInput::Make(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeTranslation(), and impeller::Entity::SetTransform().

◆ TEST_P() [361/419]

impeller::testing::TEST_P ( GaussianBlurFilterContentsTest  ,
RenderCoverageMatchesGetCoverage   
)

Definition at line 213 of file gaussian_blur_filter_contents_unittests.cc.

213  {
214  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
215  fml::StatusOr<Scalar> sigma_radius_1 =
216  CalculateSigmaForBlurRadius(1.0, Matrix());
217  ASSERT_TRUE(sigma_radius_1.ok());
218  auto contents = std::make_unique<GaussianBlurFilterContents>(
219  sigma_radius_1.value(), sigma_radius_1.value(), Entity::TileMode::kDecal,
220  FilterContents::BlurStyle::kNormal, /*mask_geometry=*/nullptr);
221  contents->SetInputs({FilterInput::Make(texture)});
222  std::shared_ptr<ContentContext> renderer = GetContentContext();
223 
224  Entity entity;
225  std::optional<Entity> result =
226  contents->GetEntity(*renderer, entity, /*coverage_hint=*/{});
227  EXPECT_TRUE(result.has_value());
228  if (result.has_value()) {
229  EXPECT_EQ(result.value().GetBlendMode(), BlendMode::kSourceOver);
230  std::optional<Rect> result_coverage = result.value().GetCoverage();
231  std::optional<Rect> contents_coverage = contents->GetCoverage(entity);
232  EXPECT_TRUE(result_coverage.has_value());
233  EXPECT_TRUE(contents_coverage.has_value());
234  if (result_coverage.has_value() && contents_coverage.has_value()) {
235  EXPECT_TRUE(RectNear(contents_coverage.value(),
236  Rect::MakeLTRB(-1, -1, 101, 101)));
237  EXPECT_TRUE(
238  RectNear(result_coverage.value(), Rect::MakeLTRB(-1, -1, 101, 101)));
239  }
240  }
241 }

References impeller::Entity::kDecal, impeller::FilterContents::kNormal, impeller::kSourceOver, impeller::FilterInput::Make(), impeller::TRect< Scalar >::MakeLTRB(), and RectNear().

◆ TEST_P() [362/419]

impeller::testing::TEST_P ( GaussianBlurFilterContentsTest  ,
RenderCoverageMatchesGetCoverageRotated   
)

Definition at line 276 of file gaussian_blur_filter_contents_unittests.cc.

277  {
278  std::shared_ptr<Texture> texture = MakeTexture(ISize(400, 300));
279  fml::StatusOr<Scalar> sigma_radius_1 =
280  CalculateSigmaForBlurRadius(1.0, Matrix());
281  auto contents = std::make_unique<GaussianBlurFilterContents>(
282  sigma_radius_1.value(), sigma_radius_1.value(), Entity::TileMode::kDecal,
283  FilterContents::BlurStyle::kNormal, /*mask_geometry=*/nullptr);
284  contents->SetInputs({FilterInput::Make(texture)});
285  std::shared_ptr<ContentContext> renderer = GetContentContext();
286 
287  Entity entity;
288  // Rotate around the top left corner, then push it over to (100, 100).
289  entity.SetTransform(Matrix::MakeTranslation({400, 100, 0}) *
290  Matrix::MakeRotationZ(Degrees(90.0)));
291  std::optional<Entity> result =
292  contents->GetEntity(*renderer, entity, /*coverage_hint=*/{});
293  EXPECT_TRUE(result.has_value());
294  if (result.has_value()) {
295  EXPECT_EQ(result.value().GetBlendMode(), BlendMode::kSourceOver);
296  std::optional<Rect> result_coverage = result.value().GetCoverage();
297  std::optional<Rect> contents_coverage = contents->GetCoverage(entity);
298  EXPECT_TRUE(result_coverage.has_value());
299  EXPECT_TRUE(contents_coverage.has_value());
300  if (result_coverage.has_value() && contents_coverage.has_value()) {
301  EXPECT_TRUE(RectNear(contents_coverage.value(),
302  Rect::MakeLTRB(99, 99, 401, 501)));
303  EXPECT_TRUE(
304  RectNear(result_coverage.value(), Rect::MakeLTRB(99, 99, 401, 501)));
305  }
306  }
307 }

References impeller::Entity::kDecal, impeller::FilterContents::kNormal, impeller::kSourceOver, impeller::FilterInput::Make(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeRotationZ(), impeller::Matrix::MakeTranslation(), RectNear(), and impeller::Entity::SetTransform().

◆ TEST_P() [363/419]

impeller::testing::TEST_P ( GaussianBlurFilterContentsTest  ,
RenderCoverageMatchesGetCoverageTranslate   
)

Definition at line 243 of file gaussian_blur_filter_contents_unittests.cc.

244  {
245  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
246  fml::StatusOr<Scalar> sigma_radius_1 =
247  CalculateSigmaForBlurRadius(1.0, Matrix());
248  ASSERT_TRUE(sigma_radius_1.ok());
249  auto contents = std::make_unique<GaussianBlurFilterContents>(
250  sigma_radius_1.value(), sigma_radius_1.value(), Entity::TileMode::kDecal,
251  FilterContents::BlurStyle::kNormal, /*mask_geometry=*/nullptr);
252  contents->SetInputs({FilterInput::Make(texture)});
253  std::shared_ptr<ContentContext> renderer = GetContentContext();
254 
255  Entity entity;
256  entity.SetTransform(Matrix::MakeTranslation({100, 200, 0}));
257  std::optional<Entity> result =
258  contents->GetEntity(*renderer, entity, /*coverage_hint=*/{});
259 
260  EXPECT_TRUE(result.has_value());
261  if (result.has_value()) {
262  EXPECT_EQ(result.value().GetBlendMode(), BlendMode::kSourceOver);
263  std::optional<Rect> result_coverage = result.value().GetCoverage();
264  std::optional<Rect> contents_coverage = contents->GetCoverage(entity);
265  EXPECT_TRUE(result_coverage.has_value());
266  EXPECT_TRUE(contents_coverage.has_value());
267  if (result_coverage.has_value() && contents_coverage.has_value()) {
268  EXPECT_TRUE(RectNear(contents_coverage.value(),
269  Rect::MakeLTRB(99, 199, 201, 301)));
270  EXPECT_TRUE(
271  RectNear(result_coverage.value(), Rect::MakeLTRB(99, 199, 201, 301)));
272  }
273  }
274 }

References impeller::Entity::kDecal, impeller::FilterContents::kNormal, impeller::kSourceOver, impeller::FilterInput::Make(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeTranslation(), RectNear(), and impeller::Entity::SetTransform().

◆ TEST_P() [364/419]

impeller::testing::TEST_P ( GaussianBlurFilterContentsTest  ,
TextureContentsWithDestinationRect   
)

Definition at line 322 of file gaussian_blur_filter_contents_unittests.cc.

322  {
323  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
324  auto texture_contents = std::make_shared<TextureContents>();
325  texture_contents->SetSourceRect(Rect::MakeSize(texture->GetSize()));
326  texture_contents->SetTexture(texture);
327  texture_contents->SetDestinationRect(Rect::MakeXYWH(
328  50, 40, texture->GetSize().width, texture->GetSize().height));
329 
330  fml::StatusOr<Scalar> sigma_radius_1 =
331  CalculateSigmaForBlurRadius(1.0, Matrix());
332  auto contents = std::make_unique<GaussianBlurFilterContents>(
333  sigma_radius_1.value(), sigma_radius_1.value(), Entity::TileMode::kDecal,
334  FilterContents::BlurStyle::kNormal, /*mask_geometry=*/nullptr);
335  contents->SetInputs({FilterInput::Make(texture_contents)});
336  std::shared_ptr<ContentContext> renderer = GetContentContext();
337 
338  Entity entity;
339  std::optional<Entity> result =
340  contents->GetEntity(*renderer, entity, /*coverage_hint=*/{});
341  EXPECT_TRUE(result.has_value());
342  if (result.has_value()) {
343  EXPECT_EQ(result.value().GetBlendMode(), BlendMode::kSourceOver);
344  std::optional<Rect> result_coverage = result.value().GetCoverage();
345  std::optional<Rect> contents_coverage = contents->GetCoverage(entity);
346  EXPECT_TRUE(result_coverage.has_value());
347  EXPECT_TRUE(contents_coverage.has_value());
348  if (result_coverage.has_value() && contents_coverage.has_value()) {
349  EXPECT_TRUE(RectNear(result_coverage.value(), contents_coverage.value()));
350  EXPECT_TRUE(RectNear(result_coverage.value(),
351  Rect::MakeLTRB(49.f, 39.f, 151.f, 141.f)));
352  }
353  }
354 }

References impeller::Entity::kDecal, impeller::FilterContents::kNormal, impeller::kSourceOver, impeller::FilterInput::Make(), impeller::TRect< Scalar >::MakeLTRB(), impeller::TRect< Scalar >::MakeSize(), impeller::TRect< Scalar >::MakeXYWH(), and RectNear().

◆ TEST_P() [365/419]

impeller::testing::TEST_P ( GaussianBlurFilterContentsTest  ,
TextureContentsWithDestinationRectScaled   
)

Definition at line 356 of file gaussian_blur_filter_contents_unittests.cc.

357  {
358  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
359  auto texture_contents = std::make_shared<TextureContents>();
360  texture_contents->SetSourceRect(Rect::MakeSize(texture->GetSize()));
361  texture_contents->SetTexture(texture);
362  texture_contents->SetDestinationRect(Rect::MakeXYWH(
363  50, 40, texture->GetSize().width, texture->GetSize().height));
364 
365  fml::StatusOr<Scalar> sigma_radius_1 =
366  CalculateSigmaForBlurRadius(1.0, Matrix());
367  auto contents = std::make_unique<GaussianBlurFilterContents>(
368  sigma_radius_1.value(), sigma_radius_1.value(), Entity::TileMode::kDecal,
369  FilterContents::BlurStyle::kNormal, /*mask_geometry=*/nullptr);
370  contents->SetInputs({FilterInput::Make(texture_contents)});
371  std::shared_ptr<ContentContext> renderer = GetContentContext();
372 
373  Entity entity;
374  entity.SetTransform(Matrix::MakeScale({2.0, 2.0, 1.0}));
375  std::optional<Entity> result =
376  contents->GetEntity(*renderer, entity, /*coverage_hint=*/{});
377  EXPECT_TRUE(result.has_value());
378  if (result.has_value()) {
379  EXPECT_EQ(result.value().GetBlendMode(), BlendMode::kSourceOver);
380  std::optional<Rect> result_coverage = result.value().GetCoverage();
381  std::optional<Rect> contents_coverage = contents->GetCoverage(entity);
382  EXPECT_TRUE(result_coverage.has_value());
383  EXPECT_TRUE(contents_coverage.has_value());
384  if (result_coverage.has_value() && contents_coverage.has_value()) {
385  EXPECT_TRUE(RectNear(result_coverage.value(), contents_coverage.value()));
386  EXPECT_TRUE(RectNear(contents_coverage.value(),
387  Rect::MakeLTRB(98.f, 78.f, 302.f, 282.f)));
388  }
389  }
390 }

References impeller::Entity::kDecal, impeller::FilterContents::kNormal, impeller::kSourceOver, impeller::FilterInput::Make(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeScale(), impeller::TRect< Scalar >::MakeSize(), impeller::TRect< Scalar >::MakeXYWH(), RectNear(), and impeller::Entity::SetTransform().

◆ TEST_P() [366/419]

impeller::testing::TEST_P ( GaussianBlurFilterContentsTest  ,
TextureContentsWithEffectTransform   
)

Definition at line 392 of file gaussian_blur_filter_contents_unittests.cc.

392  {
393  Matrix effect_transform = Matrix::MakeScale({2.0, 2.0, 1.0});
394  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
395  auto texture_contents = std::make_shared<TextureContents>();
396  texture_contents->SetSourceRect(Rect::MakeSize(texture->GetSize()));
397  texture_contents->SetTexture(texture);
398  texture_contents->SetDestinationRect(Rect::MakeXYWH(
399  50, 40, texture->GetSize().width, texture->GetSize().height));
400 
401  fml::StatusOr<Scalar> sigma_radius_1 =
402  CalculateSigmaForBlurRadius(1.0, effect_transform);
403  ASSERT_TRUE(sigma_radius_1.ok());
404  auto contents = std::make_unique<GaussianBlurFilterContents>(
405  sigma_radius_1.value(), sigma_radius_1.value(), Entity::TileMode::kDecal,
406  FilterContents::BlurStyle::kNormal, /*mask_geometry=*/nullptr);
407  contents->SetInputs({FilterInput::Make(texture_contents)});
408  contents->SetEffectTransform(effect_transform);
409  std::shared_ptr<ContentContext> renderer = GetContentContext();
410 
411  Entity entity;
412  std::optional<Entity> result =
413  contents->GetEntity(*renderer, entity, /*coverage_hint=*/{});
414  EXPECT_TRUE(result.has_value());
415  if (result.has_value()) {
416  EXPECT_EQ(result.value().GetBlendMode(), BlendMode::kSourceOver);
417  std::optional<Rect> result_coverage = result.value().GetCoverage();
418  std::optional<Rect> contents_coverage = contents->GetCoverage(entity);
419  EXPECT_TRUE(result_coverage.has_value());
420  EXPECT_TRUE(contents_coverage.has_value());
421  if (result_coverage.has_value() && contents_coverage.has_value()) {
422  EXPECT_TRUE(RectNear(result_coverage.value(), contents_coverage.value()));
423  EXPECT_TRUE(RectNear(contents_coverage.value(),
424  Rect::MakeXYWH(49.f, 39.f, 102.f, 102.f)));
425  }
426  }
427 }

References impeller::Entity::kDecal, impeller::FilterContents::kNormal, impeller::kSourceOver, impeller::FilterInput::Make(), impeller::Matrix::MakeScale(), impeller::TRect< Scalar >::MakeSize(), impeller::TRect< Scalar >::MakeXYWH(), and RectNear().

◆ TEST_P() [367/419]

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

Definition at line 15 of file host_buffer_unittests.cc.

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

References impeller::HostBuffer::Create().

◆ TEST_P() [368/419]

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

Definition at line 30 of file host_buffer_unittests.cc.

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

References impeller::HostBuffer::Create().

◆ TEST_P() [369/419]

impeller::testing::TEST_P ( HostBufferTest  ,
EmplaceWithProcIsAligned   
)

Definition at line 149 of file host_buffer_unittests.cc.

149  {
150  auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
151 
152  BufferView view = buffer->Emplace(std::array<char, 21>());
153  EXPECT_EQ(view.range, Range(0, 21));
154 
155  view = buffer->Emplace(64, 16, [](uint8_t*) {});
156  EXPECT_EQ(view.range, Range(32, 64));
157 }

References impeller::HostBuffer::Create(), and impeller::BufferView::range.

◆ TEST_P() [370/419]

impeller::testing::TEST_P ( HostBufferTest  ,
EmplacingLargerThanBlockSizeCreatesOneOffBuffer   
)

Definition at line 106 of file host_buffer_unittests.cc.

106  {
107  auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
108 
109  // Emplace an amount larger than the block size, to verify that the host
110  // buffer does not create a buffer.
111  auto buffer_view = buffer->Emplace(nullptr, 1024000 + 10, 0);
112 
113  EXPECT_EQ(buffer->GetStateForTest().current_buffer, 0u);
114  EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u);
115  EXPECT_EQ(buffer->GetStateForTest().total_buffer_count, 1u);
116 }

References impeller::HostBuffer::Create().

◆ TEST_P() [371/419]

impeller::testing::TEST_P ( HostBufferTest  ,
EmplacingLargerThanBlockSizeCreatesOneOffBufferCallback   
)

Definition at line 93 of file host_buffer_unittests.cc.

94  {
95  auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
96 
97  // Emplace an amount larger than the block size, to verify that the host
98  // buffer does not create a buffer.
99  auto buffer_view = buffer->Emplace(1024000 + 10, 0, [](uint8_t* data) {});
100 
101  EXPECT_EQ(buffer->GetStateForTest().current_buffer, 0u);
102  EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u);
103  EXPECT_EQ(buffer->GetStateForTest().total_buffer_count, 1u);
104 }

References impeller::HostBuffer::Create().

◆ TEST_P() [372/419]

impeller::testing::TEST_P ( HostBufferTest  ,
HostBufferInitialState   
)

Definition at line 70 of file host_buffer_unittests.cc.

70  {
71  auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
72 
73  EXPECT_EQ(buffer->GetStateForTest().current_buffer, 0u);
74  EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u);
75  EXPECT_EQ(buffer->GetStateForTest().total_buffer_count, 1u);
76 }

References impeller::HostBuffer::Create().

◆ TEST_P() [373/419]

impeller::testing::TEST_P ( HostBufferTest  ,
ResetIncrementsFrameCounter   
)

Definition at line 78 of file host_buffer_unittests.cc.

78  {
79  auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
80 
81  EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u);
82 
83  buffer->Reset();
84  EXPECT_EQ(buffer->GetStateForTest().current_frame, 1u);
85 
86  buffer->Reset();
87  EXPECT_EQ(buffer->GetStateForTest().current_frame, 2u);
88 
89  buffer->Reset();
90  EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u);
91 }

References impeller::HostBuffer::Create().

◆ TEST_P() [374/419]

impeller::testing::TEST_P ( HostBufferTest  ,
UnusedBuffersAreDiscardedWhenResetting   
)

Definition at line 118 of file host_buffer_unittests.cc.

118  {
119  auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
120 
121  // Emplace two large allocations to force the allocation of a second buffer.
122  auto buffer_view_a = buffer->Emplace(1020000, 0, [](uint8_t* data) {});
123  auto buffer_view_b = buffer->Emplace(1020000, 0, [](uint8_t* data) {});
124 
125  EXPECT_EQ(buffer->GetStateForTest().current_buffer, 1u);
126  EXPECT_EQ(buffer->GetStateForTest().total_buffer_count, 2u);
127  EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u);
128 
129  // Reset until we get back to this frame.
130  for (auto i = 0; i < 3; i++) {
131  buffer->Reset();
132  }
133 
134  EXPECT_EQ(buffer->GetStateForTest().current_buffer, 0u);
135  EXPECT_EQ(buffer->GetStateForTest().total_buffer_count, 2u);
136  EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u);
137 
138  // Now when we reset, the buffer should get dropped.
139  // Reset until we get back to this frame.
140  for (auto i = 0; i < 3; i++) {
141  buffer->Reset();
142  }
143 
144  EXPECT_EQ(buffer->GetStateForTest().current_buffer, 0u);
145  EXPECT_EQ(buffer->GetStateForTest().total_buffer_count, 1u);
146  EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u);
147 }

References impeller::HostBuffer::Create().

◆ TEST_P() [375/419]

impeller::testing::TEST_P ( RendererDartTest  ,
CanInstantiateFlutterGPUContext   
)

Definition at line 103 of file renderer_dart_unittests.cc.

103  {
104  auto isolate = GetIsolate();
105  bool result = isolate->RunInIsolateScope([]() -> bool {
106  if (tonic::CheckAndHandleError(::Dart_Invoke(
107  Dart_RootLibrary(), tonic::ToDart("instantiateDefaultContext"), 0,
108  nullptr))) {
109  return false;
110  }
111  return true;
112  });
113 
114  ASSERT_TRUE(result);
115 }

◆ TEST_P() [376/419]

impeller::testing::TEST_P ( RendererDartTest  ,
CanRunDartInPlaygroundFrame   
)

Definition at line 83 of file renderer_dart_unittests.cc.

83  {
84  auto isolate = GetIsolate();
85 
86  SinglePassCallback callback = [&](RenderPass& pass) {
87  ImGui::Begin("Dart test", nullptr);
88  ImGui::Text(
89  "This test executes Dart code during the playground frame callback.");
90  ImGui::End();
91 
92  return isolate->RunInIsolateScope([]() -> bool {
93  if (tonic::CheckAndHandleError(::Dart_Invoke(
94  Dart_RootLibrary(), tonic::ToDart("sayHi"), 0, nullptr))) {
95  return false;
96  }
97  return true;
98  });
99  };
100  OpenPlaygroundHere(callback);
101 }

◆ TEST_P() [377/419]

impeller::testing::TEST_P ( RendererTest  ,
ArrayUniforms   
)

Definition at line 887 of file renderer_unittests.cc.

887  {
888  using VS = ArrayVertexShader;
889  using FS = ArrayFragmentShader;
890 
891  auto context = GetContext();
892  auto pipeline_descriptor =
893  PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
894  ASSERT_TRUE(pipeline_descriptor.has_value());
895  pipeline_descriptor->SetSampleCount(SampleCount::kCount4);
896  pipeline_descriptor->SetStencilAttachmentDescriptors(std::nullopt);
897  auto pipeline =
898  context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
899  ASSERT_TRUE(pipeline && pipeline->IsValid());
900 
901  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
902  SinglePassCallback callback = [&](RenderPass& pass) {
903  auto size = pass.GetRenderTargetSize();
904 
905  pass.SetPipeline(pipeline);
906  pass.SetCommandLabel("Google Dots");
907  VertexBufferBuilder<VS::PerVertexData> builder;
908  builder.AddVertices({{Point()},
909  {Point(0, size.height)},
910  {Point(size.width, 0)},
911  {Point(size.width, 0)},
912  {Point(0, size.height)},
913  {Point(size.width, size.height)}});
914  pass.SetVertexBuffer(builder.CreateVertexBuffer(*host_buffer));
915 
916  VS::FrameInfo frame_info;
917  EXPECT_EQ(pass.GetOrthographicTransform(), Matrix::MakeOrthographic(size));
918  frame_info.mvp =
919  pass.GetOrthographicTransform() * Matrix::MakeScale(GetContentScale());
920  VS::BindFrameInfo(pass, host_buffer->EmplaceUniform(frame_info));
921 
922  auto time = GetSecondsElapsed();
923  auto y_pos = [&time](float x) {
924  return 400 + 10 * std::cos(time * 5 + x / 6);
925  };
926 
927  FS::FragInfo fs_uniform = {
928  .circle_positions = {Point(430, y_pos(0)), Point(480, y_pos(1)),
929  Point(530, y_pos(2)), Point(580, y_pos(3))},
930  .colors = {Color::MakeRGBA8(66, 133, 244, 255),
931  Color::MakeRGBA8(219, 68, 55, 255),
932  Color::MakeRGBA8(244, 180, 0, 255),
933  Color::MakeRGBA8(15, 157, 88, 255)},
934  };
935  FS::BindFragInfo(pass, host_buffer->EmplaceUniform(fs_uniform));
936 
937  pass.Draw();
938  host_buffer->Reset();
939  return true;
940  };
941  OpenPlaygroundHere(callback);
942 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::HostBuffer::Create(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::kCount4, impeller::PipelineBuilder< VertexShader_, FragmentShader_ >::MakeDefaultPipelineDescriptor(), impeller::Matrix::MakeOrthographic(), impeller::Color::MakeRGBA8(), and impeller::Matrix::MakeScale().

◆ TEST_P() [378/419]

impeller::testing::TEST_P ( RendererTest  ,
CachesRenderPassAndFramebuffer   
)

Definition at line 16 of file render_pass_cache_unittests.cc.

16  {
17  if (GetBackend() != PlaygroundBackend::kVulkan) {
18  GTEST_SKIP() << "Test only applies to Vulkan";
19  }
20 
21  auto allocator = std::make_shared<RenderTargetAllocator>(
22  GetContext()->GetResourceAllocator());
23 
24  auto render_target =
25  allocator->CreateOffscreenMSAA(*GetContext(), {100, 100}, 1);
26  auto resolve_texture =
27  render_target.GetColorAttachments().find(0u)->second.resolve_texture;
28  auto& texture_vk = TextureVK::Cast(*resolve_texture);
29 
30  EXPECT_EQ(texture_vk.GetCachedFramebuffer(), nullptr);
31  EXPECT_EQ(texture_vk.GetCachedRenderPass(), nullptr);
32 
33  auto buffer = GetContext()->CreateCommandBuffer();
34  auto render_pass = buffer->CreateRenderPass(render_target);
35 
36  EXPECT_NE(texture_vk.GetCachedFramebuffer(), nullptr);
37  EXPECT_NE(texture_vk.GetCachedRenderPass(), nullptr);
38 
39  render_pass->EncodeCommands();
40  GetContext()->GetCommandQueue()->Submit({buffer});
41 
42  // Can be reused without error.
43  auto buffer_2 = GetContext()->CreateCommandBuffer();
44  auto render_pass_2 = buffer_2->CreateRenderPass(render_target);
45 
46  EXPECT_TRUE(render_pass_2->EncodeCommands());
47  EXPECT_TRUE(GetContext()->GetCommandQueue()->Submit({buffer_2}).ok());
48 }

References impeller::BackendCast< TextureVK, Texture >::Cast(), and impeller::kVulkan.

◆ TEST_P() [379/419]

impeller::testing::TEST_P ( RendererTest  ,
CanBlitTextureToBuffer   
)

Definition at line 570 of file renderer_unittests.cc.

570  {
571  if (GetBackend() == PlaygroundBackend::kOpenGLES) {
572  GTEST_SKIP() << "Mipmap test shader not supported on GLES.";
573  }
574  auto context = GetContext();
575  ASSERT_TRUE(context);
576 
577  using VS = MipmapsVertexShader;
578  using FS = MipmapsFragmentShader;
579  auto desc = PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
580  ASSERT_TRUE(desc.has_value());
581  desc->SetSampleCount(SampleCount::kCount4);
582  desc->SetStencilAttachmentDescriptors(std::nullopt);
583  auto mipmaps_pipeline =
584  context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
585  ASSERT_TRUE(mipmaps_pipeline);
586 
587  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
588  auto boston = CreateTextureForFixture("boston.jpg");
589  ASSERT_TRUE(bridge && boston);
590  const std::unique_ptr<const Sampler>& sampler =
591  context->GetSamplerLibrary()->GetSampler({});
592  ASSERT_TRUE(sampler);
593 
594  TextureDescriptor texture_desc;
595  texture_desc.storage_mode = StorageMode::kHostVisible;
596  texture_desc.format = PixelFormat::kR8G8B8A8UNormInt;
597  texture_desc.size = bridge->GetTextureDescriptor().size;
598  texture_desc.mip_count = 1u;
599  texture_desc.usage = TextureUsage::kRenderTarget |
600  TextureUsage::kShaderWrite | TextureUsage::kShaderRead;
601  DeviceBufferDescriptor device_buffer_desc;
602  device_buffer_desc.storage_mode = StorageMode::kHostVisible;
603  device_buffer_desc.size =
604  bridge->GetTextureDescriptor().GetByteSizeOfBaseMipLevel();
605  auto device_buffer =
606  context->GetResourceAllocator()->CreateBuffer(device_buffer_desc);
607 
608  // Vertex buffer.
609  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
610  vertex_builder.SetLabel("Box");
611  auto size = Point(boston->GetSize());
612  vertex_builder.AddVertices({
613  {{0, 0}, {0.0, 0.0}}, // 1
614  {{size.x, 0}, {1.0, 0.0}}, // 2
615  {{size.x, size.y}, {1.0, 1.0}}, // 3
616  {{0, 0}, {0.0, 0.0}}, // 1
617  {{size.x, size.y}, {1.0, 1.0}}, // 3
618  {{0, size.y}, {0.0, 1.0}}, // 4
619  });
620  auto vertex_buffer =
621  vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator());
622  ASSERT_TRUE(vertex_buffer);
623 
624  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
625  Renderer::RenderCallback callback = [&](RenderTarget& render_target) {
626  {
627  auto buffer = context->CreateCommandBuffer();
628  if (!buffer) {
629  return false;
630  }
631  buffer->SetLabel("Playground Command Buffer");
632  auto pass = buffer->CreateBlitPass();
633  if (!pass) {
634  return false;
635  }
636  pass->SetLabel("Playground Blit Pass");
637 
638  if (render_target.GetColorAttachments().empty()) {
639  return false;
640  }
641 
642  // Blit `bridge` to the top left corner of the texture.
643  pass->AddCopy(bridge, device_buffer);
644  pass->EncodeCommands(context->GetResourceAllocator());
645 
646  if (!context->GetCommandQueue()->Submit({buffer}).ok()) {
647  return false;
648  }
649  }
650 
651  {
652  auto buffer = context->CreateCommandBuffer();
653  if (!buffer) {
654  return false;
655  }
656  buffer->SetLabel("Playground Command Buffer");
657 
658  auto pass = buffer->CreateRenderPass(render_target);
659  if (!pass) {
660  return false;
661  }
662  pass->SetLabel("Playground Render Pass");
663  {
664  pass->SetCommandLabel("Image");
665  pass->SetPipeline(mipmaps_pipeline);
666  pass->SetVertexBuffer(vertex_buffer);
667 
668  VS::FrameInfo frame_info;
669  EXPECT_EQ(pass->GetOrthographicTransform(),
670  Matrix::MakeOrthographic(pass->GetRenderTargetSize()));
671  frame_info.mvp = pass->GetOrthographicTransform() *
672  Matrix::MakeScale(GetContentScale());
673  VS::BindFrameInfo(*pass, host_buffer->EmplaceUniform(frame_info));
674 
675  FS::FragInfo frag_info;
676  frag_info.lod = 0;
677  FS::BindFragInfo(*pass, host_buffer->EmplaceUniform(frag_info));
678 
679  const std::unique_ptr<const Sampler>& sampler =
680  context->GetSamplerLibrary()->GetSampler({});
681  auto buffer_view = DeviceBuffer::AsBufferView(device_buffer);
682  auto texture =
683  context->GetResourceAllocator()->CreateTexture(texture_desc);
684  if (!texture->SetContents(device_buffer->OnGetContents(),
685  buffer_view.range.length)) {
686  VALIDATION_LOG << "Could not upload texture to device memory";
687  return false;
688  }
689  FS::BindTex(*pass, texture, sampler);
690 
691  pass->Draw().ok();
692  }
693  pass->EncodeCommands();
694  if (!context->GetCommandQueue()->Submit({buffer}).ok()) {
695  return false;
696  }
697  }
698  host_buffer->Reset();
699  return true;
700  };
701  OpenPlaygroundHere(callback);
702 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::DeviceBuffer::AsBufferView(), impeller::HostBuffer::Create(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::TextureDescriptor::format, impeller::kCount4, impeller::kHostVisible, impeller::kOpenGLES, impeller::kR8G8B8A8UNormInt, impeller::kRenderTarget, impeller::kShaderRead, impeller::kShaderWrite, impeller::PipelineBuilder< VertexShader_, FragmentShader_ >::MakeDefaultPipelineDescriptor(), impeller::Matrix::MakeOrthographic(), impeller::Matrix::MakeScale(), impeller::TextureDescriptor::mip_count, 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() [380/419]

impeller::testing::TEST_P ( RendererTest  ,
CanBlitTextureToTexture   
)

Definition at line 455 of file renderer_unittests.cc.

455  {
456  if (GetBackend() == PlaygroundBackend::kOpenGLES) {
457  GTEST_SKIP() << "Mipmap test shader not supported on GLES.";
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 = TextureUsage::kRenderTarget | TextureUsage::kShaderRead;
478  auto texture = context->GetResourceAllocator()->CreateTexture(texture_desc);
479  ASSERT_TRUE(texture);
480 
481  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
482  auto boston = CreateTextureForFixture("boston.jpg");
483  ASSERT_TRUE(bridge && boston);
484  const std::unique_ptr<const Sampler>& sampler =
485  context->GetSamplerLibrary()->GetSampler({});
486  ASSERT_TRUE(sampler);
487 
488  // Vertex buffer.
489  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
490  vertex_builder.SetLabel("Box");
491  auto size = Point(boston->GetSize());
492  vertex_builder.AddVertices({
493  {{0, 0}, {0.0, 0.0}}, // 1
494  {{size.x, 0}, {1.0, 0.0}}, // 2
495  {{size.x, size.y}, {1.0, 1.0}}, // 3
496  {{0, 0}, {0.0, 0.0}}, // 1
497  {{size.x, size.y}, {1.0, 1.0}}, // 3
498  {{0, size.y}, {0.0, 1.0}}, // 4
499  });
500  auto vertex_buffer =
501  vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator());
502  ASSERT_TRUE(vertex_buffer);
503 
504  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
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  pass->SetCommandLabel("Image");
539  pass->SetPipeline(mipmaps_pipeline);
540  pass->SetVertexBuffer(vertex_buffer);
541 
542  VS::FrameInfo frame_info;
543  EXPECT_EQ(pass->GetOrthographicTransform(),
544  Matrix::MakeOrthographic(pass->GetRenderTargetSize()));
545  frame_info.mvp = pass->GetOrthographicTransform() *
546  Matrix::MakeScale(GetContentScale());
547  VS::BindFrameInfo(*pass, host_buffer->EmplaceUniform(frame_info));
548 
549  FS::FragInfo frag_info;
550  frag_info.lod = 0;
551  FS::BindFragInfo(*pass, host_buffer->EmplaceUniform(frag_info));
552 
553  auto& sampler = context->GetSamplerLibrary()->GetSampler({});
554  FS::BindTex(*pass, texture, sampler);
555 
556  pass->Draw();
557  }
558  pass->EncodeCommands();
559  }
560 
561  if (!context->GetCommandQueue()->Submit({buffer}).ok()) {
562  return false;
563  }
564  host_buffer->Reset();
565  return true;
566  };
567  OpenPlaygroundHere(callback);
568 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::HostBuffer::Create(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::TextureDescriptor::format, impeller::kCount4, impeller::kHostVisible, impeller::kOpenGLES, impeller::kR8G8B8A8UNormInt, impeller::kRenderTarget, impeller::kShaderRead, impeller::PipelineBuilder< VertexShader_, FragmentShader_ >::MakeDefaultPipelineDescriptor(), impeller::Matrix::MakeOrthographic(), impeller::Matrix::MakeScale(), impeller::TextureDescriptor::mip_count, impeller::VertexBufferBuilder< VertexType_, IndexType_ >::SetLabel(), impeller::TextureDescriptor::size, impeller::TextureDescriptor::storage_mode, and impeller::TextureDescriptor::usage.

◆ TEST_P() [381/419]

impeller::testing::TEST_P ( RendererTest  ,
CanCreateBoxPrimitive   
)

Definition at line 53 of file renderer_unittests.cc.

53  {
54  using VS = BoxFadeVertexShader;
55  using FS = BoxFadeFragmentShader;
56  auto context = GetContext();
57  ASSERT_TRUE(context);
58  using BoxPipelineBuilder = PipelineBuilder<VS, FS>;
59  auto desc = BoxPipelineBuilder::MakeDefaultPipelineDescriptor(*context);
60  ASSERT_TRUE(desc.has_value());
61  desc->SetSampleCount(SampleCount::kCount4);
62  desc->SetStencilAttachmentDescriptors(std::nullopt);
63 
64  // Vertex buffer.
65  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
66  vertex_builder.SetLabel("Box");
67  vertex_builder.AddVertices({
68  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
69  {{800, 100, 0.0}, {1.0, 0.0}}, // 2
70  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
71  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
72  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
73  {{100, 800, 0.0}, {0.0, 1.0}}, // 4
74  });
75  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
76  auto boston = CreateTextureForFixture("boston.jpg");
77  ASSERT_TRUE(bridge && boston);
78  const std::unique_ptr<const Sampler>& sampler =
79  context->GetSamplerLibrary()->GetSampler({});
80  ASSERT_TRUE(sampler);
81 
82  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
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  pass.SetCommandLabel("Box");
95  pass.SetPipeline(pipeline);
96  pass.SetVertexBuffer(
97  vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator()));
98 
99  VS::UniformBuffer uniforms;
100  EXPECT_EQ(pass.GetOrthographicTransform(),
101  Matrix::MakeOrthographic(pass.GetRenderTargetSize()));
102  uniforms.mvp =
103  pass.GetOrthographicTransform() * Matrix::MakeScale(GetContentScale());
104  VS::BindUniformBuffer(pass, host_buffer->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(pass, host_buffer->EmplaceUniform(frame_info));
113  FS::BindContents1(pass, boston, sampler);
114  FS::BindContents2(pass, bridge, sampler);
115 
116  host_buffer->Reset();
117  return pass.Draw().ok();
118  };
119  OpenPlaygroundHere(callback);
120 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::HostBuffer::Create(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::kCount4, impeller::kFill, impeller::kLine, impeller::Matrix::MakeOrthographic(), impeller::Matrix::MakeScale(), and impeller::VertexBufferBuilder< VertexType_, IndexType_ >::SetLabel().

◆ TEST_P() [382/419]

impeller::testing::TEST_P ( RendererTest  ,
CanCreateCPUBackedTexture   
)

Definition at line 991 of file renderer_unittests.cc.

991  {
992  if (GetParam() == PlaygroundBackend::kOpenGLES) {
993  GTEST_SKIP_("CPU backed textures are not supported on OpenGLES.");
994  }
995 
996  auto context = GetContext();
997  auto allocator = context->GetResourceAllocator();
998  size_t dimension = 2;
999 
1000  do {
1001  ISize size(dimension, dimension);
1002  TextureDescriptor texture_descriptor;
1003  texture_descriptor.storage_mode = StorageMode::kHostVisible;
1004  texture_descriptor.format = PixelFormat::kR8G8B8A8UNormInt;
1005  texture_descriptor.size = size;
1006  auto row_bytes =
1007  std::max(static_cast<uint16_t>(size.width * 4),
1008  allocator->MinimumBytesPerRow(texture_descriptor.format));
1009  auto buffer_size = size.height * row_bytes;
1010 
1011  DeviceBufferDescriptor buffer_descriptor;
1012  buffer_descriptor.storage_mode = StorageMode::kHostVisible;
1013  buffer_descriptor.size = buffer_size;
1014 
1015  auto buffer = allocator->CreateBuffer(buffer_descriptor);
1016 
1017  ASSERT_TRUE(buffer);
1018 
1019  auto texture = buffer->AsTexture(*allocator, texture_descriptor, row_bytes);
1020 
1021  ASSERT_TRUE(texture);
1022  ASSERT_TRUE(texture->IsValid());
1023 
1024  dimension *= 2;
1025  } while (dimension <= 8192);
1026 }

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

impeller::testing::TEST_P ( RendererTest  ,
CanGenerateMipmaps   
)

Definition at line 704 of file renderer_unittests.cc.

704  {
705  if (GetBackend() == PlaygroundBackend::kOpenGLES) {
706  GTEST_SKIP() << "Mipmap test shader not supported on GLES.";
707  }
708  auto context = GetContext();
709  ASSERT_TRUE(context);
710 
711  using VS = MipmapsVertexShader;
712  using FS = MipmapsFragmentShader;
713  auto desc = PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
714  ASSERT_TRUE(desc.has_value());
715  desc->SetSampleCount(SampleCount::kCount4);
716  desc->SetStencilAttachmentDescriptors(std::nullopt);
717  auto mipmaps_pipeline =
718  context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
719  ASSERT_TRUE(mipmaps_pipeline);
720 
721  auto boston = CreateTextureForFixture("boston.jpg", true);
722  ASSERT_TRUE(boston);
723 
724  // Vertex buffer.
725  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
726  vertex_builder.SetLabel("Box");
727  auto size = Point(boston->GetSize());
728  vertex_builder.AddVertices({
729  {{0, 0}, {0.0, 0.0}}, // 1
730  {{size.x, 0}, {1.0, 0.0}}, // 2
731  {{size.x, size.y}, {1.0, 1.0}}, // 3
732  {{0, 0}, {0.0, 0.0}}, // 1
733  {{size.x, size.y}, {1.0, 1.0}}, // 3
734  {{0, size.y}, {0.0, 1.0}}, // 4
735  });
736  auto vertex_buffer =
737  vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator());
738  ASSERT_TRUE(vertex_buffer);
739 
740  bool first_frame = true;
741  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
742  Renderer::RenderCallback callback = [&](RenderTarget& render_target) {
743  const char* mip_filter_names[] = {"Nearest", "Linear"};
744  const MipFilter mip_filters[] = {MipFilter::kNearest, MipFilter::kLinear};
745  const char* min_filter_names[] = {"Nearest", "Linear"};
746  const MinMagFilter min_filters[] = {MinMagFilter::kNearest,
747  MinMagFilter::kLinear};
748 
749  // UI state.
750  static int selected_mip_filter = 1;
751  static int selected_min_filter = 0;
752  static float lod = 4.5;
753 
754  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
755  ImGui::Combo("Mip filter", &selected_mip_filter, mip_filter_names,
756  sizeof(mip_filter_names) / sizeof(char*));
757  ImGui::Combo("Min filter", &selected_min_filter, min_filter_names,
758  sizeof(min_filter_names) / sizeof(char*));
759  ImGui::SliderFloat("LOD", &lod, 0, boston->GetMipCount() - 1);
760  ImGui::End();
761 
762  auto buffer = context->CreateCommandBuffer();
763  if (!buffer) {
764  return false;
765  }
766  buffer->SetLabel("Playground Command Buffer");
767 
768  if (first_frame) {
769  auto pass = buffer->CreateBlitPass();
770  if (!pass) {
771  return false;
772  }
773  pass->SetLabel("Playground Blit Pass");
774 
775  pass->GenerateMipmap(boston, "Boston Mipmap");
776 
777  pass->EncodeCommands(context->GetResourceAllocator());
778  }
779 
780  first_frame = false;
781 
782  {
783  auto pass = buffer->CreateRenderPass(render_target);
784  if (!pass) {
785  return false;
786  }
787  pass->SetLabel("Playground Render Pass");
788  {
789  pass->SetCommandLabel("Image LOD");
790  pass->SetPipeline(mipmaps_pipeline);
791  pass->SetVertexBuffer(vertex_buffer);
792 
793  VS::FrameInfo frame_info;
794  EXPECT_EQ(pass->GetOrthographicTransform(),
795  Matrix::MakeOrthographic(pass->GetRenderTargetSize()));
796  frame_info.mvp = pass->GetOrthographicTransform() *
797  Matrix::MakeScale(GetContentScale());
798  VS::BindFrameInfo(*pass, host_buffer->EmplaceUniform(frame_info));
799 
800  FS::FragInfo frag_info;
801  frag_info.lod = lod;
802  FS::BindFragInfo(*pass, host_buffer->EmplaceUniform(frag_info));
803 
804  SamplerDescriptor sampler_desc;
805  sampler_desc.mip_filter = mip_filters[selected_mip_filter];
806  sampler_desc.min_filter = min_filters[selected_min_filter];
807  const std::unique_ptr<const Sampler>& sampler =
808  context->GetSamplerLibrary()->GetSampler(sampler_desc);
809  FS::BindTex(*pass, boston, sampler);
810 
811  pass->Draw();
812  }
813  pass->EncodeCommands();
814  }
815 
816  if (!context->GetCommandQueue()->Submit({buffer}).ok()) {
817  return false;
818  }
819  host_buffer->Reset();
820  return true;
821  };
822  OpenPlaygroundHere(callback);
823 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::HostBuffer::Create(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::kCount4, impeller::kLinear, impeller::kNearest, impeller::kOpenGLES, impeller::PipelineBuilder< VertexShader_, FragmentShader_ >::MakeDefaultPipelineDescriptor(), impeller::Matrix::MakeOrthographic(), impeller::Matrix::MakeScale(), impeller::SamplerDescriptor::min_filter, impeller::SamplerDescriptor::mip_filter, and impeller::VertexBufferBuilder< VertexType_, IndexType_ >::SetLabel().

◆ TEST_P() [384/419]

impeller::testing::TEST_P ( RendererTest  ,
CanLookupRenderTargetProperties   
)

Definition at line 1268 of file renderer_unittests.cc.

1268  {
1269  auto context = GetContext();
1270  auto cmd_buffer = context->CreateCommandBuffer();
1271  auto render_target_cache = std::make_shared<RenderTargetAllocator>(
1272  GetContext()->GetResourceAllocator());
1273 
1274  auto render_target = render_target_cache->CreateOffscreen(
1275  *context, {100, 100}, /*mip_count=*/1);
1276  auto render_pass = cmd_buffer->CreateRenderPass(render_target);
1277 
1278  EXPECT_EQ(render_pass->GetSampleCount(), render_target.GetSampleCount());
1279  EXPECT_EQ(render_pass->GetRenderTargetPixelFormat(),
1280  render_target.GetRenderTargetPixelFormat());
1281  EXPECT_EQ(render_pass->HasStencilAttachment(),
1282  render_target.GetStencilAttachment().has_value());
1283  EXPECT_EQ(render_pass->GetRenderTargetSize(),
1284  render_target.GetRenderTargetSize());
1285  render_pass->EncodeCommands();
1286 }

◆ TEST_P() [385/419]

impeller::testing::TEST_P ( RendererTest  ,
CanRenderInstanced   
)

Definition at line 387 of file renderer_unittests.cc.

387  {
388  if (GetParam() == PlaygroundBackend::kOpenGLES) {
389  GTEST_SKIP_("Instancing is not supported on OpenGL.");
390  }
391  using VS = InstancedDrawVertexShader;
392  using FS = InstancedDrawFragmentShader;
393 
394  VertexBufferBuilder<VS::PerVertexData> builder;
395 
396  ASSERT_EQ(Tessellator::Result::kSuccess,
397  Tessellator{}.Tessellate(
398  PathBuilder{}
399  .AddRect(Rect::MakeXYWH(10, 10, 100, 100))
400  .TakePath(FillType::kOdd),
401  1.0f,
402  [&builder](const float* vertices, size_t vertices_count,
403  const uint16_t* indices, size_t indices_count) {
404  for (auto i = 0u; i < vertices_count * 2; i += 2) {
405  VS::PerVertexData data;
406  data.vtx = {vertices[i], vertices[i + 1]};
407  builder.AppendVertex(data);
408  }
409  for (auto i = 0u; i < indices_count; i++) {
410  builder.AppendIndex(indices[i]);
411  }
412  return true;
413  }));
414 
415  ASSERT_NE(GetContext(), nullptr);
416  auto pipeline =
417  GetContext()
418  ->GetPipelineLibrary()
419  ->GetPipeline(PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(
420  *GetContext())
421  ->SetSampleCount(SampleCount::kCount4)
422  .SetStencilAttachmentDescriptors(std::nullopt))
423 
424  .Get();
425  ASSERT_TRUE(pipeline && pipeline->IsValid());
426 
427  static constexpr size_t kInstancesCount = 5u;
428  VS::InstanceInfo<kInstancesCount> instances;
429  for (size_t i = 0; i < kInstancesCount; i++) {
430  instances.colors[i] = Color::Random();
431  }
432 
433  auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
434  ASSERT_TRUE(OpenPlaygroundHere([&](RenderPass& pass) -> bool {
435  pass.SetPipeline(pipeline);
436  pass.SetCommandLabel("InstancedDraw");
437 
438  VS::FrameInfo frame_info;
439  EXPECT_EQ(pass.GetOrthographicTransform(),
440  Matrix::MakeOrthographic(pass.GetRenderTargetSize()));
441  frame_info.mvp =
442  pass.GetOrthographicTransform() * Matrix::MakeScale(GetContentScale());
443  VS::BindFrameInfo(pass, host_buffer->EmplaceUniform(frame_info));
444  VS::BindInstanceInfo(pass, host_buffer->EmplaceStorageBuffer(instances));
445  pass.SetVertexBuffer(builder.CreateVertexBuffer(*host_buffer));
446 
447  pass.SetInstanceCount(kInstancesCount);
448  pass.Draw();
449 
450  host_buffer->Reset();
451  return true;
452  }));
453 }

References impeller::PathBuilder::AddRect(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AppendIndex(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AppendVertex(), impeller::HostBuffer::Create(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::RenderPass::Draw(), impeller::RenderPass::GetOrthographicTransform(), impeller::RenderPass::GetRenderTargetSize(), impeller::kCount4, impeller::kOdd, impeller::kOpenGLES, impeller::Tessellator::kSuccess, impeller::Matrix::MakeOrthographic(), impeller::Matrix::MakeScale(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Color::Random(), impeller::RenderPass::SetCommandLabel(), impeller::RenderPass::SetInstanceCount(), impeller::RenderPass::SetPipeline(), impeller::RenderPass::SetVertexBuffer(), and impeller::Tessellator::Tessellate().

◆ TEST_P() [386/419]

impeller::testing::TEST_P ( RendererTest  ,
CanRenderMultiplePrimitives   
)

Definition at line 211 of file renderer_unittests.cc.

211  {
212  using VS = BoxFadeVertexShader;
213  using FS = BoxFadeFragmentShader;
214  auto context = GetContext();
215  ASSERT_TRUE(context);
216  using BoxPipelineBuilder = PipelineBuilder<VS, FS>;
217  auto desc = BoxPipelineBuilder::MakeDefaultPipelineDescriptor(*context);
218  ASSERT_TRUE(desc.has_value());
219  desc->SetSampleCount(SampleCount::kCount4);
220  desc->SetStencilAttachmentDescriptors(std::nullopt);
221  auto box_pipeline =
222  context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
223  ASSERT_TRUE(box_pipeline);
224 
225  // Vertex buffer.
226  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
227  vertex_builder.SetLabel("Box");
228  vertex_builder.AddVertices({
229  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
230  {{800, 100, 0.0}, {1.0, 0.0}}, // 2
231  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
232  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
233  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
234  {{100, 800, 0.0}, {0.0, 1.0}}, // 4
235  });
236  auto vertex_buffer =
237  vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator());
238  ASSERT_TRUE(vertex_buffer);
239 
240  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
241  auto boston = CreateTextureForFixture("boston.jpg");
242  ASSERT_TRUE(bridge && boston);
243  const std::unique_ptr<const Sampler>& sampler =
244  context->GetSamplerLibrary()->GetSampler({});
245  ASSERT_TRUE(sampler);
246 
247  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
248  SinglePassCallback callback = [&](RenderPass& pass) {
249  for (size_t i = 0; i < 1; i++) {
250  for (size_t j = 0; j < 1; j++) {
251  pass.SetCommandLabel("Box");
252  pass.SetPipeline(box_pipeline);
253  pass.SetVertexBuffer(vertex_buffer);
254 
255  FS::FrameInfo frame_info;
256  frame_info.current_time = GetSecondsElapsed();
257  frame_info.cursor_position = GetCursorPosition();
258  frame_info.window_size.x = GetWindowSize().width;
259  frame_info.window_size.y = GetWindowSize().height;
260 
261  FS::BindFrameInfo(pass, host_buffer->EmplaceUniform(frame_info));
262  FS::BindContents1(pass, boston, sampler);
263  FS::BindContents2(pass, bridge, sampler);
264 
265  VS::UniformBuffer uniforms;
266  EXPECT_EQ(pass.GetOrthographicTransform(),
267  Matrix::MakeOrthographic(pass.GetRenderTargetSize()));
268  uniforms.mvp = pass.GetOrthographicTransform() *
269  Matrix::MakeScale(GetContentScale()) *
270  Matrix::MakeTranslation({i * 50.0f, j * 50.0f, 0.0f});
271  VS::BindUniformBuffer(pass, host_buffer->EmplaceUniform(uniforms));
272  if (!pass.Draw().ok()) {
273  return false;
274  }
275  }
276  }
277 
278  host_buffer->Reset();
279  return true;
280  };
281  OpenPlaygroundHere(callback);
282 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::HostBuffer::Create(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::kCount4, impeller::Matrix::MakeOrthographic(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), and impeller::VertexBufferBuilder< VertexType_, IndexType_ >::SetLabel().

◆ TEST_P() [387/419]

impeller::testing::TEST_P ( RendererTest  ,
CanRenderPerspectiveCube   
)

Definition at line 122 of file renderer_unittests.cc.

122  {
123  using VS = ColorsVertexShader;
124  using FS = ColorsFragmentShader;
125  auto context = GetContext();
126  ASSERT_TRUE(context);
127  auto desc = PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
128  ASSERT_TRUE(desc.has_value());
129  desc->SetCullMode(CullMode::kBackFace);
130  desc->SetWindingOrder(WindingOrder::kCounterClockwise);
131  desc->SetSampleCount(SampleCount::kCount4);
132  desc->SetStencilAttachmentDescriptors(std::nullopt);
133  auto pipeline =
134  context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
135  ASSERT_TRUE(pipeline);
136 
137  struct Cube {
138  VS::PerVertexData vertices[8] = {
139  // -Z
140  {{-1, -1, -1}, Color::Red()},
141  {{1, -1, -1}, Color::Yellow()},
142  {{1, 1, -1}, Color::Green()},
143  {{-1, 1, -1}, Color::Blue()},
144  // +Z
145  {{-1, -1, 1}, Color::Green()},
146  {{1, -1, 1}, Color::Blue()},
147  {{1, 1, 1}, Color::Red()},
148  {{-1, 1, 1}, Color::Yellow()},
149  };
150  uint16_t indices[36] = {
151  1, 5, 2, 2, 5, 6, // +X
152  4, 0, 7, 7, 0, 3, // -X
153  4, 5, 0, 0, 5, 1, // +Y
154  3, 2, 7, 7, 2, 6, // -Y
155  5, 4, 6, 6, 4, 7, // +Z
156  0, 1, 3, 3, 1, 2, // -Z
157  };
158  } cube;
159 
160  VertexBuffer vertex_buffer;
161  {
162  auto device_buffer = context->GetResourceAllocator()->CreateBufferWithCopy(
163  reinterpret_cast<uint8_t*>(&cube), sizeof(cube));
164  vertex_buffer.vertex_buffer = {
165  .buffer = device_buffer,
166  .range = Range(offsetof(Cube, vertices), sizeof(Cube::vertices))};
167  vertex_buffer.index_buffer = {
168  .buffer = device_buffer,
169  .range = Range(offsetof(Cube, indices), sizeof(Cube::indices))};
170  vertex_buffer.vertex_count = 36;
171  vertex_buffer.index_type = IndexType::k16bit;
172  }
173 
174  const std::unique_ptr<const Sampler>& sampler =
175  context->GetSamplerLibrary()->GetSampler({});
176  ASSERT_TRUE(sampler);
177 
178  Vector3 euler_angles;
179  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
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  pass.SetCommandLabel("Perspective Cube");
190  pass.SetPipeline(pipeline);
191  pass.SetVertexBuffer(vertex_buffer);
192 
193  VS::UniformBuffer uniforms;
194  Scalar time = GetSecondsElapsed();
195  euler_angles = Vector3(0.19 * time, 0.7 * time, 0.43 * time);
196 
197  uniforms.mvp =
198  Matrix::MakePerspective(fov_y, pass.GetRenderTargetSize(), 0, 10) *
199  Matrix::MakeTranslation({0, 0, distance}) *
200  Matrix::MakeRotationX(Radians(euler_angles.x)) *
201  Matrix::MakeRotationY(Radians(euler_angles.y)) *
202  Matrix::MakeRotationZ(Radians(euler_angles.z));
203  VS::BindUniformBuffer(pass, host_buffer->EmplaceUniform(uniforms));
204 
205  host_buffer->Reset();
206  return pass.Draw().ok();
207  };
208  OpenPlaygroundHere(callback);
209 }

References impeller::Color::Blue(), impeller::BufferView::buffer, impeller::HostBuffer::Create(), impeller::Degrees::degrees, impeller::saturated::distance, 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::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() [388/419]

impeller::testing::TEST_P ( RendererTest  ,
CanRenderToTexture   
)

Definition at line 284 of file renderer_unittests.cc.

284  {
285  using VS = BoxFadeVertexShader;
286  using FS = BoxFadeFragmentShader;
287  auto context = GetContext();
288  ASSERT_TRUE(context);
289  using BoxPipelineBuilder = PipelineBuilder<VS, FS>;
290  auto pipeline_desc =
291  BoxPipelineBuilder::MakeDefaultPipelineDescriptor(*context);
292  pipeline_desc->SetSampleCount(SampleCount::kCount1);
293  pipeline_desc->ClearDepthAttachment();
294  pipeline_desc->SetStencilPixelFormat(PixelFormat::kS8UInt);
295 
296  ASSERT_TRUE(pipeline_desc.has_value());
297  auto box_pipeline =
298  context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
299  ASSERT_TRUE(box_pipeline);
300  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
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  const std::unique_ptr<const Sampler>& sampler =
320  context->GetSamplerLibrary()->GetSampler({});
321  ASSERT_TRUE(sampler);
322 
323  std::shared_ptr<RenderPass> r2t_pass;
324  auto cmd_buffer = context->CreateCommandBuffer();
325  ASSERT_TRUE(cmd_buffer);
326  {
327  ColorAttachment color0;
328  color0.load_action = LoadAction::kClear;
329  color0.store_action = StoreAction::kStore;
330 
331  TextureDescriptor texture_descriptor;
332  ASSERT_NE(pipeline_desc->GetColorAttachmentDescriptor(0u), nullptr);
333  texture_descriptor.format =
334  pipeline_desc->GetColorAttachmentDescriptor(0u)->format;
335  texture_descriptor.storage_mode = StorageMode::kHostVisible;
336  texture_descriptor.size = {400, 400};
337  texture_descriptor.mip_count = 1u;
338  texture_descriptor.usage = TextureUsage::kRenderTarget;
339 
340  color0.texture =
341  context->GetResourceAllocator()->CreateTexture(texture_descriptor);
342 
343  ASSERT_TRUE(color0.IsValid());
344 
345  color0.texture->SetLabel("r2t_target");
346 
347  StencilAttachment stencil0;
348  stencil0.load_action = LoadAction::kClear;
349  stencil0.store_action = StoreAction::kDontCare;
350  TextureDescriptor stencil_texture_desc;
351  stencil_texture_desc.storage_mode = StorageMode::kDeviceTransient;
352  stencil_texture_desc.size = texture_descriptor.size;
353  stencil_texture_desc.format = PixelFormat::kS8UInt;
354  stencil_texture_desc.usage = 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  r2t_pass->SetCommandLabel("Box");
366  r2t_pass->SetPipeline(box_pipeline);
367  r2t_pass->SetVertexBuffer(vertex_buffer);
368 
369  FS::FrameInfo frame_info;
370  frame_info.current_time = GetSecondsElapsed();
371  frame_info.cursor_position = GetCursorPosition();
372  frame_info.window_size.x = GetWindowSize().width;
373  frame_info.window_size.y = GetWindowSize().height;
374 
375  FS::BindFrameInfo(*r2t_pass, host_buffer->EmplaceUniform(frame_info));
376  FS::BindContents1(*r2t_pass, boston, sampler);
377  FS::BindContents2(*r2t_pass, bridge, sampler);
378 
379  VS::UniformBuffer uniforms;
380  uniforms.mvp = Matrix::MakeOrthographic(ISize{1024, 768}) *
381  Matrix::MakeTranslation({50.0f, 50.0f, 0.0f});
382  VS::BindUniformBuffer(*r2t_pass, host_buffer->EmplaceUniform(uniforms));
383  ASSERT_TRUE(r2t_pass->Draw().ok());
384  ASSERT_TRUE(r2t_pass->EncodeCommands());
385 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::HostBuffer::Create(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), 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::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() [389/419]

impeller::testing::TEST_P ( RendererTest  ,
CanSepiaToneThenSwizzleWithSubpasses   
)

Definition at line 1416 of file renderer_unittests.cc.

1416  {
1417  // The GLES framebuffer fetch implementation currently does not support this.
1418  // TODO(chinmaygarde): revisit after the GLES framebuffer fetch capabilities
1419  // are clarified.
1420  if (GetParam() == PlaygroundBackend::kOpenGLES) {
1421  GTEST_SKIP_("Not supported on GLES.");
1422  }
1423 
1424  // Define shader types
1425  using TextureVS = TextureVertexShader;
1426  using TextureFS = TextureFragmentShader;
1427 
1428  using SwizzleVS = SepiaVertexShader;
1429  using SwizzleFS = SwizzleFragmentShader;
1430 
1431  using SepiaVS = SepiaVertexShader;
1432  using SepiaFS = SepiaFragmentShader;
1433 
1434  auto context = GetContext();
1435  ASSERT_TRUE(context);
1436 
1437  if (!context->GetCapabilities()->SupportsFramebufferFetch()) {
1438  GTEST_SKIP_(
1439  "This test uses framebuffer fetch and the backend doesn't support it.");
1440  return;
1441  }
1442 
1443  // Create pipelines.
1444  auto texture_pipeline = CreateDefaultPipeline<TextureVS, TextureFS>(context);
1445  auto swizzle_pipeline = CreateDefaultPipeline<SwizzleVS, SwizzleFS>(context);
1446  auto sepia_pipeline = CreateDefaultPipeline<SepiaVS, SepiaFS>(context);
1447 
1448  ASSERT_TRUE(texture_pipeline);
1449  ASSERT_TRUE(swizzle_pipeline);
1450  ASSERT_TRUE(sepia_pipeline);
1451 
1452  // Vertex buffer builders.
1453  VertexBufferBuilder<TextureVS::PerVertexData> texture_vtx_builder;
1454  texture_vtx_builder.AddVertices({
1455  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
1456  {{800, 100, 0.0}, {1.0, 0.0}}, // 2
1457  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
1458  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
1459  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
1460  {{100, 800, 0.0}, {0.0, 1.0}}, // 4
1461  });
1462 
1463  VertexBufferBuilder<SepiaVS::PerVertexData> sepia_vtx_builder;
1464  sepia_vtx_builder.AddVertices({
1465  {{100, 100, 0.0}}, // 1
1466  {{800, 100, 0.0}}, // 2
1467  {{800, 800, 0.0}}, // 3
1468  {{100, 100, 0.0}}, // 1
1469  {{800, 800, 0.0}}, // 3
1470  {{100, 800, 0.0}}, // 4
1471  });
1472 
1473  auto boston = CreateTextureForFixture("boston.jpg");
1474  ASSERT_TRUE(boston);
1475 
1476  const auto& sampler = context->GetSamplerLibrary()->GetSampler({});
1477  ASSERT_TRUE(sampler);
1478 
1479  SinglePassCallback callback = [&](RenderPass& pass) {
1480  auto buffer = HostBuffer::Create(context->GetResourceAllocator());
1481 
1482  // Draw the texture.
1483  {
1484  pass.SetPipeline(texture_pipeline);
1485  pass.SetVertexBuffer(texture_vtx_builder.CreateVertexBuffer(
1486  *context->GetResourceAllocator()));
1487  TextureVS::UniformBuffer uniforms;
1488  uniforms.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
1489  Matrix::MakeScale(GetContentScale());
1490  TextureVS::BindUniformBuffer(pass, buffer->EmplaceUniform(uniforms));
1491  TextureFS::BindTextureContents(pass, boston, sampler);
1492  if (!pass.Draw().ok()) {
1493  return false;
1494  }
1495  }
1496 
1497  // Draw the sepia toner.
1498  {
1499  pass.SetPipeline(sepia_pipeline);
1500  pass.SetVertexBuffer(sepia_vtx_builder.CreateVertexBuffer(
1501  *context->GetResourceAllocator()));
1502  SepiaVS::UniformBuffer uniforms;
1503  uniforms.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
1504  Matrix::MakeScale(GetContentScale());
1505  SepiaVS::BindUniformBuffer(pass, buffer->EmplaceUniform(uniforms));
1506  if (!pass.Draw().ok()) {
1507  return false;
1508  }
1509  }
1510 
1511  // Draw the swizzle.
1512  {
1513  pass.SetPipeline(swizzle_pipeline);
1514  pass.SetVertexBuffer(sepia_vtx_builder.CreateVertexBuffer(
1515  *context->GetResourceAllocator()));
1516  SwizzleVS::UniformBuffer uniforms;
1517  uniforms.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
1518  Matrix::MakeScale(GetContentScale());
1519  SwizzleVS::BindUniformBuffer(pass, buffer->EmplaceUniform(uniforms));
1520  if (!pass.Draw().ok()) {
1521  return false;
1522  }
1523  }
1524 
1525  return true;
1526  };
1527  OpenPlaygroundHere(callback);
1528 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::HostBuffer::Create(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::kOpenGLES, impeller::Matrix::MakeOrthographic(), and impeller::Matrix::MakeScale().

◆ TEST_P() [390/419]

impeller::testing::TEST_P ( RendererTest  ,
CanSepiaToneWithSubpasses   
)

Definition at line 1321 of file renderer_unittests.cc.

1321  {
1322  // The GLES framebuffer fetch implementation currently does not support this.
1323  // TODO(chinmaygarde): revisit after the GLES framebuffer fetch capabilities
1324  // are clarified.
1325  if (GetParam() == PlaygroundBackend::kOpenGLES) {
1326  GTEST_SKIP_("Not supported on GLES.");
1327  }
1328 
1329  // Define shader types
1330  using TextureVS = TextureVertexShader;
1331  using TextureFS = TextureFragmentShader;
1332 
1333  using SepiaVS = SepiaVertexShader;
1334  using SepiaFS = SepiaFragmentShader;
1335 
1336  auto context = GetContext();
1337  ASSERT_TRUE(context);
1338 
1339  if (!context->GetCapabilities()->SupportsFramebufferFetch()) {
1340  GTEST_SKIP_(
1341  "This test uses framebuffer fetch and the backend doesn't support it.");
1342  return;
1343  }
1344 
1345  // Create pipelines.
1346  auto texture_pipeline = CreateDefaultPipeline<TextureVS, TextureFS>(context);
1347  auto sepia_pipeline = CreateDefaultPipeline<SepiaVS, SepiaFS>(context);
1348 
1349  ASSERT_TRUE(texture_pipeline);
1350  ASSERT_TRUE(sepia_pipeline);
1351 
1352  // Vertex buffer builders.
1353  VertexBufferBuilder<TextureVS::PerVertexData> texture_vtx_builder;
1354  texture_vtx_builder.AddVertices({
1355  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
1356  {{800, 100, 0.0}, {1.0, 0.0}}, // 2
1357  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
1358  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
1359  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
1360  {{100, 800, 0.0}, {0.0, 1.0}}, // 4
1361  });
1362 
1363  VertexBufferBuilder<SepiaVS::PerVertexData> sepia_vtx_builder;
1364  sepia_vtx_builder.AddVertices({
1365  {{100, 100, 0.0}}, // 1
1366  {{800, 100, 0.0}}, // 2
1367  {{800, 800, 0.0}}, // 3
1368  {{100, 100, 0.0}}, // 1
1369  {{800, 800, 0.0}}, // 3
1370  {{100, 800, 0.0}}, // 4
1371  });
1372 
1373  auto boston = CreateTextureForFixture("boston.jpg");
1374  ASSERT_TRUE(boston);
1375 
1376  const auto& sampler = context->GetSamplerLibrary()->GetSampler({});
1377  ASSERT_TRUE(sampler);
1378 
1379  SinglePassCallback callback = [&](RenderPass& pass) {
1380  auto buffer = HostBuffer::Create(context->GetResourceAllocator());
1381 
1382  // Draw the texture.
1383  {
1384  pass.SetPipeline(texture_pipeline);
1385  pass.SetVertexBuffer(texture_vtx_builder.CreateVertexBuffer(
1386  *context->GetResourceAllocator()));
1387  TextureVS::UniformBuffer uniforms;
1388  uniforms.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
1389  Matrix::MakeScale(GetContentScale());
1390  TextureVS::BindUniformBuffer(pass, buffer->EmplaceUniform(uniforms));
1391  TextureFS::BindTextureContents(pass, boston, sampler);
1392  if (!pass.Draw().ok()) {
1393  return false;
1394  }
1395  }
1396 
1397  // Draw the sepia toner.
1398  {
1399  pass.SetPipeline(sepia_pipeline);
1400  pass.SetVertexBuffer(sepia_vtx_builder.CreateVertexBuffer(
1401  *context->GetResourceAllocator()));
1402  SepiaVS::UniformBuffer uniforms;
1403  uniforms.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
1404  Matrix::MakeScale(GetContentScale());
1405  SepiaVS::BindUniformBuffer(pass, buffer->EmplaceUniform(uniforms));
1406  if (!pass.Draw().ok()) {
1407  return false;
1408  }
1409  }
1410 
1411  return true;
1412  };
1413  OpenPlaygroundHere(callback);
1414 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::HostBuffer::Create(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::kOpenGLES, impeller::Matrix::MakeOrthographic(), and impeller::Matrix::MakeScale().

◆ TEST_P() [391/419]

impeller::testing::TEST_P ( RendererTest  ,
DefaultIndexBehavior   
)

Definition at line 1038 of file renderer_unittests.cc.

1038  {
1039  using VS = BoxFadeVertexShader;
1040 
1041  // Do not create any index buffer if no indices were provided.
1042  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
1043  ASSERT_EQ(vertex_builder.GetIndexType(), IndexType::kNone);
1044 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::GetIndexType(), and impeller::kNone.

◆ TEST_P() [392/419]

impeller::testing::TEST_P ( RendererTest  ,
DefaultIndexSize   
)

Definition at line 1028 of file renderer_unittests.cc.

1028  {
1029  using VS = BoxFadeVertexShader;
1030 
1031  // Default to 16bit index buffer size, as this is a reasonable default and
1032  // supported on all backends without extensions.
1033  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
1034  vertex_builder.AppendIndex(0u);
1035  ASSERT_EQ(vertex_builder.GetIndexType(), IndexType::k16bit);
1036 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AppendIndex(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::GetIndexType(), and impeller::k16bit.

◆ TEST_P() [393/419]

impeller::testing::TEST_P ( RendererTest  ,
InactiveUniforms   
)

Definition at line 944 of file renderer_unittests.cc.

944  {
945  using VS = InactiveUniformsVertexShader;
946  using FS = InactiveUniformsFragmentShader;
947 
948  auto context = GetContext();
949  auto pipeline_descriptor =
950  PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
951  ASSERT_TRUE(pipeline_descriptor.has_value());
952  pipeline_descriptor->SetSampleCount(SampleCount::kCount4);
953  pipeline_descriptor->SetStencilAttachmentDescriptors(std::nullopt);
954  auto pipeline =
955  context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
956  ASSERT_TRUE(pipeline && pipeline->IsValid());
957 
958  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
959  SinglePassCallback callback = [&](RenderPass& pass) {
960  auto size = pass.GetRenderTargetSize();
961 
962  pass.SetPipeline(pipeline);
963  pass.SetCommandLabel("Inactive Uniform");
964 
965  VertexBufferBuilder<VS::PerVertexData> builder;
966  builder.AddVertices({{Point()},
967  {Point(0, size.height)},
968  {Point(size.width, 0)},
969  {Point(size.width, 0)},
970  {Point(0, size.height)},
971  {Point(size.width, size.height)}});
972  pass.SetVertexBuffer(builder.CreateVertexBuffer(*host_buffer));
973 
974  VS::FrameInfo frame_info;
975  EXPECT_EQ(pass.GetOrthographicTransform(), Matrix::MakeOrthographic(size));
976  frame_info.mvp =
977  pass.GetOrthographicTransform() * Matrix::MakeScale(GetContentScale());
978  VS::BindFrameInfo(pass, host_buffer->EmplaceUniform(frame_info));
979 
980  FS::FragInfo fs_uniform = {.unused_color = Color::Red(),
981  .color = Color::Green()};
982  FS::BindFragInfo(pass, host_buffer->EmplaceUniform(fs_uniform));
983 
984  pass.Draw().ok();
985  host_buffer->Reset();
986  return true;
987  };
988  OpenPlaygroundHere(callback);
989 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::HostBuffer::Create(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::Color::Green(), impeller::kCount4, impeller::PipelineBuilder< VertexShader_, FragmentShader_ >::MakeDefaultPipelineDescriptor(), impeller::Matrix::MakeOrthographic(), impeller::Matrix::MakeScale(), and impeller::Color::Red().

◆ TEST_P() [394/419]

impeller::testing::TEST_P ( RendererTest  ,
RenderTargetCreateOffscreenMSAASetsDefaultDepthStencilFormat   
)

Definition at line 1288 of file renderer_unittests.cc.

1289  {
1290  auto context = GetContext();
1291  auto render_target_cache = std::make_shared<RenderTargetAllocator>(
1292  GetContext()->GetResourceAllocator());
1293 
1294  RenderTarget render_target = render_target_cache->CreateOffscreenMSAA(
1295  *context, {100, 100}, /*mip_count=*/1);
1296  EXPECT_EQ(render_target.GetDepthAttachment()
1297  ->texture->GetTextureDescriptor()
1298  .format,
1299  GetContext()->GetCapabilities()->GetDefaultDepthStencilFormat());
1300 }

References impeller::RenderTarget::GetDepthAttachment().

◆ TEST_P() [395/419]

impeller::testing::TEST_P ( RendererTest  ,
StencilMask   
)

Definition at line 1116 of file renderer_unittests.cc.

1116  {
1117  using VS = BoxFadeVertexShader;
1118  using FS = BoxFadeFragmentShader;
1119  auto context = GetContext();
1120  ASSERT_TRUE(context);
1121  using BoxFadePipelineBuilder = PipelineBuilder<VS, FS>;
1122  auto desc = BoxFadePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
1123  ASSERT_TRUE(desc.has_value());
1124 
1125  // Vertex buffer.
1126  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
1127  vertex_builder.SetLabel("Box");
1128  vertex_builder.AddVertices({
1129  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
1130  {{800, 100, 0.0}, {1.0, 0.0}}, // 2
1131  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
1132  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
1133  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
1134  {{100, 800, 0.0}, {0.0, 1.0}}, // 4
1135  });
1136  auto vertex_buffer =
1137  vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator());
1138  ASSERT_TRUE(vertex_buffer);
1139 
1140  desc->SetSampleCount(SampleCount::kCount4);
1141  desc->SetStencilAttachmentDescriptors(std::nullopt);
1142 
1143  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
1144  auto boston = CreateTextureForFixture("boston.jpg");
1145  ASSERT_TRUE(bridge && boston);
1146  const std::unique_ptr<const Sampler>& sampler =
1147  context->GetSamplerLibrary()->GetSampler({});
1148  ASSERT_TRUE(sampler);
1149 
1150  static bool mirror = false;
1151  static int stencil_reference_write = 0xFF;
1152  static int stencil_reference_read = 0x1;
1153  std::vector<uint8_t> stencil_contents;
1154  static int last_stencil_contents_reference_value = 0;
1155  static int current_front_compare =
1156  CompareFunctionUI().IndexOf(CompareFunction::kLessEqual);
1157  static int current_back_compare =
1158  CompareFunctionUI().IndexOf(CompareFunction::kLessEqual);
1159 
1160  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
1161  Renderer::RenderCallback callback = [&](RenderTarget& render_target) {
1162  auto buffer = context->CreateCommandBuffer();
1163  if (!buffer) {
1164  return false;
1165  }
1166  buffer->SetLabel("Playground Command Buffer");
1167 
1168  {
1169  // Configure the stencil attachment for the test.
1170  RenderTarget::AttachmentConfig stencil_config;
1171  stencil_config.load_action = LoadAction::kLoad;
1172  stencil_config.store_action = StoreAction::kDontCare;
1173  stencil_config.storage_mode = StorageMode::kHostVisible;
1174  render_target.SetupDepthStencilAttachments(
1175  *context, *context->GetResourceAllocator(),
1176  render_target.GetRenderTargetSize(), true, "stencil", stencil_config);
1177  // Fill the stencil buffer with an checkerboard pattern.
1178  const auto target_width = render_target.GetRenderTargetSize().width;
1179  const auto target_height = render_target.GetRenderTargetSize().height;
1180  const size_t target_size = target_width * target_height;
1181  if (stencil_contents.size() != target_size ||
1182  last_stencil_contents_reference_value != stencil_reference_write) {
1183  stencil_contents.resize(target_size);
1184  last_stencil_contents_reference_value = stencil_reference_write;
1185  for (int y = 0; y < target_height; y++) {
1186  for (int x = 0; x < target_width; x++) {
1187  const auto index = y * target_width + x;
1188  const auto kCheckSize = 64;
1189  const auto value =
1190  (((y / kCheckSize) + (x / kCheckSize)) % 2 == 0) *
1191  stencil_reference_write;
1192  stencil_contents[index] = value;
1193  }
1194  }
1195  }
1196  if (!render_target.GetStencilAttachment()->texture->SetContents(
1197  stencil_contents.data(), stencil_contents.size(), 0, false)) {
1198  VALIDATION_LOG << "Could not upload stencil contents to device memory";
1199  return false;
1200  }
1201  auto pass = buffer->CreateRenderPass(render_target);
1202  if (!pass) {
1203  return false;
1204  }
1205  pass->SetLabel("Stencil Buffer");
1206  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1207  ImGui::SliderInt("Stencil Write Value", &stencil_reference_write, 0,
1208  0xFF);
1209  ImGui::SliderInt("Stencil Compare Value", &stencil_reference_read, 0,
1210  0xFF);
1211  ImGui::Checkbox("Back face mode", &mirror);
1212  ImGui::ListBox("Front face compare function", &current_front_compare,
1213  CompareFunctionUI().labels(), CompareFunctionUI().size());
1214  ImGui::ListBox("Back face compare function", &current_back_compare,
1215  CompareFunctionUI().labels(), CompareFunctionUI().size());
1216  ImGui::End();
1217 
1218  StencilAttachmentDescriptor front;
1219  front.stencil_compare =
1220  CompareFunctionUI().FunctionOf(current_front_compare);
1221  StencilAttachmentDescriptor back;
1222  back.stencil_compare =
1223  CompareFunctionUI().FunctionOf(current_back_compare);
1224  desc->SetStencilAttachmentDescriptors(front, back);
1225  auto pipeline = context->GetPipelineLibrary()->GetPipeline(desc).Get();
1226 
1227  assert(pipeline && pipeline->IsValid());
1228 
1229  pass->SetCommandLabel("Box");
1230  pass->SetPipeline(pipeline);
1231  pass->SetStencilReference(stencil_reference_read);
1232  pass->SetVertexBuffer(vertex_buffer);
1233 
1234  VS::UniformBuffer uniforms;
1235  EXPECT_EQ(pass->GetOrthographicTransform(),
1236  Matrix::MakeOrthographic(pass->GetRenderTargetSize()));
1237  uniforms.mvp = pass->GetOrthographicTransform() *
1238  Matrix::MakeScale(GetContentScale());
1239  if (mirror) {
1240  uniforms.mvp = Matrix::MakeScale(Vector2(-1, 1)) * uniforms.mvp;
1241  }
1242  VS::BindUniformBuffer(*pass, host_buffer->EmplaceUniform(uniforms));
1243 
1244  FS::FrameInfo frame_info;
1245  frame_info.current_time = GetSecondsElapsed();
1246  frame_info.cursor_position = GetCursorPosition();
1247  frame_info.window_size.x = GetWindowSize().width;
1248  frame_info.window_size.y = GetWindowSize().height;
1249 
1250  FS::BindFrameInfo(*pass, host_buffer->EmplaceUniform(frame_info));
1251  FS::BindContents1(*pass, boston, sampler);
1252  FS::BindContents2(*pass, bridge, sampler);
1253  if (!pass->Draw().ok()) {
1254  return false;
1255  }
1256  pass->EncodeCommands();
1257  }
1258 
1259  if (!context->GetCommandQueue()->Submit({buffer}).ok()) {
1260  return false;
1261  }
1262  host_buffer->Reset();
1263  return true;
1264  };
1265  OpenPlaygroundHere(callback);
1266 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), CompareFunctionUI(), impeller::HostBuffer::Create(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), 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::VertexBufferBuilder< VertexType_, IndexType_ >::SetLabel(), impeller::StencilAttachmentDescriptor::stencil_compare, impeller::RenderTarget::AttachmentConfig::storage_mode, impeller::RenderTarget::AttachmentConfig::store_action, and VALIDATION_LOG.

◆ TEST_P() [396/419]

impeller::testing::TEST_P ( RendererTest  ,
TheImpeller   
)

Definition at line 825 of file renderer_unittests.cc.

825  {
826  using VS = ImpellerVertexShader;
827  using FS = ImpellerFragmentShader;
828 
829  auto context = GetContext();
830  auto pipeline_descriptor =
831  PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
832  ASSERT_TRUE(pipeline_descriptor.has_value());
833  pipeline_descriptor->SetSampleCount(SampleCount::kCount4);
834  pipeline_descriptor->SetStencilAttachmentDescriptors(std::nullopt);
835  auto pipeline =
836  context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
837  ASSERT_TRUE(pipeline && pipeline->IsValid());
838 
839  auto blue_noise = CreateTextureForFixture("blue_noise.png");
840  SamplerDescriptor noise_sampler_desc;
841  noise_sampler_desc.width_address_mode = SamplerAddressMode::kRepeat;
842  noise_sampler_desc.height_address_mode = SamplerAddressMode::kRepeat;
843  const std::unique_ptr<const Sampler>& noise_sampler =
844  context->GetSamplerLibrary()->GetSampler(noise_sampler_desc);
845 
846  auto cube_map = CreateTextureCubeForFixture(
847  {"table_mountain_px.png", "table_mountain_nx.png",
848  "table_mountain_py.png", "table_mountain_ny.png",
849  "table_mountain_pz.png", "table_mountain_nz.png"});
850  const std::unique_ptr<const Sampler>& cube_map_sampler =
851  context->GetSamplerLibrary()->GetSampler({});
852  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
853 
854  SinglePassCallback callback = [&](RenderPass& pass) {
855  auto size = pass.GetRenderTargetSize();
856 
857  pass.SetPipeline(pipeline);
858  pass.SetCommandLabel("Impeller SDF scene");
859  VertexBufferBuilder<VS::PerVertexData> builder;
860  builder.AddVertices({{Point()},
861  {Point(0, size.height)},
862  {Point(size.width, 0)},
863  {Point(size.width, 0)},
864  {Point(0, size.height)},
865  {Point(size.width, size.height)}});
866  pass.SetVertexBuffer(builder.CreateVertexBuffer(*host_buffer));
867 
868  VS::FrameInfo frame_info;
869  EXPECT_EQ(pass.GetOrthographicTransform(), Matrix::MakeOrthographic(size));
870  frame_info.mvp = pass.GetOrthographicTransform();
871  VS::BindFrameInfo(pass, host_buffer->EmplaceUniform(frame_info));
872 
873  FS::FragInfo fs_uniform;
874  fs_uniform.texture_size = Point(size);
875  fs_uniform.time = GetSecondsElapsed();
876  FS::BindFragInfo(pass, host_buffer->EmplaceUniform(fs_uniform));
877  FS::BindBlueNoise(pass, blue_noise, noise_sampler);
878  FS::BindCubeMap(pass, cube_map, cube_map_sampler);
879 
880  pass.Draw().ok();
881  host_buffer->Reset();
882  return true;
883  };
884  OpenPlaygroundHere(callback);
885 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::HostBuffer::Create(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::SamplerDescriptor::height_address_mode, impeller::kCount4, impeller::kRepeat, impeller::PipelineBuilder< VertexShader_, FragmentShader_ >::MakeDefaultPipelineDescriptor(), impeller::Matrix::MakeOrthographic(), and impeller::SamplerDescriptor::width_address_mode.

◆ TEST_P() [397/419]

impeller::testing::TEST_P ( RendererTest  ,
VertexBufferBuilder   
)

Definition at line 1046 of file renderer_unittests.cc.

1046  {
1047  // Does not create index buffer if one is provided.
1048  using VS = BoxFadeVertexShader;
1049  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
1050  vertex_builder.SetLabel("Box");
1051  vertex_builder.AddVertices({
1052  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
1053  {{800, 100, 0.0}, {1.0, 0.0}}, // 2
1054  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
1055  {{100, 800, 0.0}, {0.0, 1.0}}, // 4
1056  });
1057  vertex_builder.AppendIndex(0);
1058  vertex_builder.AppendIndex(1);
1059  vertex_builder.AppendIndex(2);
1060  vertex_builder.AppendIndex(1);
1061  vertex_builder.AppendIndex(2);
1062  vertex_builder.AppendIndex(3);
1063 
1064  ASSERT_EQ(vertex_builder.GetIndexCount(), 6u);
1065  ASSERT_EQ(vertex_builder.GetVertexCount(), 4u);
1066 }

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

impeller::testing::TEST_P ( RenderTargetCacheTest  ,
CachedTextureGetsNewAttachmentConfig   
)

Definition at line 90 of file render_target_cache_unittests.cc.

90  {
91  auto render_target_cache =
92  RenderTargetCache(GetContext()->GetResourceAllocator());
93 
94  render_target_cache.Start();
95  RenderTarget::AttachmentConfig color_attachment_config =
96  RenderTarget::kDefaultColorAttachmentConfig;
97  RenderTarget target1 = render_target_cache.CreateOffscreen(
98  *GetContext(), {100, 100}, 1, "Offscreen1", color_attachment_config);
99  render_target_cache.End();
100 
101  render_target_cache.Start();
102  color_attachment_config.clear_color = Color::Red();
103  RenderTarget target2 = render_target_cache.CreateOffscreen(
104  *GetContext(), {100, 100}, 1, "Offscreen2", color_attachment_config);
105  render_target_cache.End();
106 
107  auto color1 = target1.GetColorAttachments().find(0)->second;
108  auto color2 = target2.GetColorAttachments().find(0)->second;
109  // The second color attachment should reuse the first attachment's texture
110  // but with attributes from the second AttachmentConfig.
111  EXPECT_EQ(color2.texture, color1.texture);
112  EXPECT_EQ(color2.clear_color, Color::Red());
113 }

References impeller::RenderTarget::AttachmentConfig::clear_color, impeller::RenderTarget::GetColorAttachments(), impeller::RenderTarget::kDefaultColorAttachmentConfig, and impeller::Color::Red().

◆ TEST_P() [399/419]

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

Definition at line 51 of file render_target_cache_unittests.cc.

51  {
52  auto render_target_cache =
53  RenderTargetCache(GetContext()->GetResourceAllocator());
54 
55  render_target_cache.Start();
56  // Create two render targets of the same exact size/shape. Both should be
57  // marked as used this frame, so the cached data set will contain two.
58  render_target_cache.CreateOffscreen(*GetContext(), {100, 100}, 1);
59  render_target_cache.CreateOffscreen(*GetContext(), {100, 100}, 1);
60 
61  EXPECT_EQ(render_target_cache.CachedTextureCount(), 2u);
62 
63  render_target_cache.End();
64  render_target_cache.Start();
65 
66  // Next frame, only create one texture. The set will still contain two,
67  // but one will be removed at the end of the frame.
68  render_target_cache.CreateOffscreen(*GetContext(), {100, 100}, 1);
69  EXPECT_EQ(render_target_cache.CachedTextureCount(), 2u);
70 
71  render_target_cache.End();
72  EXPECT_EQ(render_target_cache.CachedTextureCount(), 1u);
73 }

◆ TEST_P() [400/419]

impeller::testing::TEST_P ( RenderTargetCacheTest  ,
CreateWithEmptySize   
)

Definition at line 115 of file render_target_cache_unittests.cc.

115  {
116  auto render_target_cache =
117  RenderTargetCache(GetContext()->GetResourceAllocator());
118 
119  render_target_cache.Start();
120  RenderTarget empty_target =
121  render_target_cache.CreateOffscreen(*GetContext(), {100, 0}, 1);
122  RenderTarget empty_target_msaa =
123  render_target_cache.CreateOffscreenMSAA(*GetContext(), {0, 0}, 1);
124  render_target_cache.End();
125 
126  {
127  ScopedValidationDisable disable_validation;
128  EXPECT_FALSE(empty_target.IsValid());
129  EXPECT_FALSE(empty_target_msaa.IsValid());
130  }
131 }

References impeller::RenderTarget::IsValid().

◆ TEST_P() [401/419]

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

Definition at line 75 of file render_target_cache_unittests.cc.

75  {
76  ScopedValidationDisable disable;
77  auto allocator = std::make_shared<TestAllocator>();
78  auto render_target_cache = RenderTargetCache(allocator);
79 
80  render_target_cache.Start();
81  allocator->should_fail = true;
82 
83  auto render_target =
84  render_target_cache.CreateOffscreen(*GetContext(), {100, 100}, 1);
85 
86  EXPECT_FALSE(render_target.IsValid());
87  EXPECT_EQ(render_target_cache.CachedTextureCount(), 0u);
88 }

◆ TEST_P() [402/419]

impeller::testing::TEST_P ( RuntimeStageTest  ,
CanCreatePipelineFromRuntimeStage   
)

Definition at line 262 of file runtime_stage_unittests.cc.

262  {
263  auto stages = OpenAssetAsRuntimeStage("ink_sparkle.frag.iplr");
264  auto stage = stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
265 
266  ASSERT_TRUE(stage);
267  ASSERT_NE(stage, nullptr);
268  ASSERT_TRUE(RegisterStage(*stage));
269  auto library = GetContext()->GetShaderLibrary();
270  using VS = RuntimeEffectVertexShader;
271  PipelineDescriptor desc;
272  desc.SetLabel("Runtime Stage InkSparkle");
273  desc.AddStageEntrypoint(
274  library->GetFunction(VS::kEntrypointName, ShaderStage::kVertex));
275  desc.AddStageEntrypoint(
276  library->GetFunction(stage->GetEntrypoint(), ShaderStage::kFragment));
277  auto vertex_descriptor = std::make_shared<VertexDescriptor>();
278  vertex_descriptor->SetStageInputs(VS::kAllShaderStageInputs,
279  VS::kInterleavedBufferLayout);
280 
281  std::array<DescriptorSetLayout, 2> descriptor_set_layouts = {
282  VS::kDescriptorSetLayouts[0],
283  DescriptorSetLayout{
284  .binding = 64u,
285  .descriptor_type = DescriptorType::kUniformBuffer,
286  .shader_stage = ShaderStage::kFragment,
287  },
288  };
289  vertex_descriptor->RegisterDescriptorSetLayouts(descriptor_set_layouts);
290 
291  desc.SetVertexDescriptor(std::move(vertex_descriptor));
292  ColorAttachmentDescriptor color0;
293  color0.format = GetContext()->GetCapabilities()->GetDefaultColorFormat();
294  StencilAttachmentDescriptor stencil0;
295  stencil0.stencil_compare = CompareFunction::kEqual;
296  desc.SetColorAttachmentDescriptor(0u, color0);
297  desc.SetStencilAttachmentDescriptors(stencil0);
298  const auto stencil_fmt =
299  GetContext()->GetCapabilities()->GetDefaultStencilFormat();
300  desc.SetStencilPixelFormat(stencil_fmt);
301  auto pipeline = GetContext()->GetPipelineLibrary()->GetPipeline(desc).Get();
302  ASSERT_NE(pipeline, nullptr);
303 }

References impeller::PipelineDescriptor::AddStageEntrypoint(), impeller::DescriptorSetLayout::binding, impeller::ColorAttachmentDescriptor::format, impeller::kEqual, impeller::kFragment, impeller::kUniformBuffer, impeller::kVertex, impeller::PlaygroundBackendToRuntimeStageBackend(), impeller::PipelineDescriptor::SetColorAttachmentDescriptor(), impeller::PipelineDescriptor::SetLabel(), impeller::PipelineDescriptor::SetStencilAttachmentDescriptors(), impeller::PipelineDescriptor::SetStencilPixelFormat(), impeller::PipelineDescriptor::SetVertexDescriptor(), and impeller::StencilAttachmentDescriptor::stencil_compare.

◆ TEST_P() [403/419]

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

Definition at line 54 of file runtime_stage_unittests.cc.

54  {
55  const std::shared_ptr<fml::Mapping> fixture =
56  flutter::testing::OpenFixtureAsMapping("ink_sparkle.frag.iplr");
57  ASSERT_TRUE(fixture);
58  ASSERT_GT(fixture->GetSize(), 0u);
59  auto stages = RuntimeStage::DecodeRuntimeStages(fixture);
60  auto stage = stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
61 
62  ASSERT_TRUE(stage->IsValid());
63  switch (GetBackend()) {
64  case PlaygroundBackend::kMetal:
65  case PlaygroundBackend::kOpenGLES: {
66  ASSERT_EQ(stage->GetUniforms().size(), 17u);
67  {
68  auto uni = stage->GetUniform("u_color");
69  ASSERT_NE(uni, nullptr);
70  EXPECT_EQ(uni->dimensions.rows, 4u);
71  EXPECT_EQ(uni->dimensions.cols, 1u);
72  EXPECT_EQ(uni->location, 0u);
73  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
74  }
75  {
76  auto uni = stage->GetUniform("u_alpha");
77  ASSERT_NE(uni, nullptr);
78  EXPECT_EQ(uni->dimensions.rows, 1u);
79  EXPECT_EQ(uni->dimensions.cols, 1u);
80  EXPECT_EQ(uni->location, 1u);
81  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
82  }
83  {
84  auto uni = stage->GetUniform("u_sparkle_color");
85  ASSERT_NE(uni, nullptr);
86  EXPECT_EQ(uni->dimensions.rows, 4u);
87  EXPECT_EQ(uni->dimensions.cols, 1u);
88  EXPECT_EQ(uni->location, 2u);
89  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
90  }
91  {
92  auto uni = stage->GetUniform("u_sparkle_alpha");
93  ASSERT_NE(uni, nullptr);
94  EXPECT_EQ(uni->dimensions.rows, 1u);
95  EXPECT_EQ(uni->dimensions.cols, 1u);
96  EXPECT_EQ(uni->location, 3u);
97  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
98  }
99  {
100  auto uni = stage->GetUniform("u_blur");
101  ASSERT_NE(uni, nullptr);
102  EXPECT_EQ(uni->dimensions.rows, 1u);
103  EXPECT_EQ(uni->dimensions.cols, 1u);
104  EXPECT_EQ(uni->location, 4u);
105  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
106  }
107  {
108  auto uni = stage->GetUniform("u_radius_scale");
109  ASSERT_NE(uni, nullptr);
110  EXPECT_EQ(uni->dimensions.rows, 1u);
111  EXPECT_EQ(uni->dimensions.cols, 1u);
112  EXPECT_EQ(uni->location, 6u);
113  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
114  }
115  {
116  auto uni = stage->GetUniform("u_max_radius");
117  ASSERT_NE(uni, nullptr);
118  EXPECT_EQ(uni->dimensions.rows, 1u);
119  EXPECT_EQ(uni->dimensions.cols, 1u);
120  EXPECT_EQ(uni->location, 7u);
121  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
122  }
123  {
124  auto uni = stage->GetUniform("u_resolution_scale");
125  ASSERT_NE(uni, nullptr);
126  EXPECT_EQ(uni->dimensions.rows, 2u);
127  EXPECT_EQ(uni->dimensions.cols, 1u);
128  EXPECT_EQ(uni->location, 8u);
129  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
130  }
131  {
132  auto uni = stage->GetUniform("u_noise_scale");
133  ASSERT_NE(uni, nullptr);
134  EXPECT_EQ(uni->dimensions.rows, 2u);
135  EXPECT_EQ(uni->dimensions.cols, 1u);
136  EXPECT_EQ(uni->location, 9u);
137  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
138  }
139  {
140  auto uni = stage->GetUniform("u_noise_phase");
141  ASSERT_NE(uni, nullptr);
142  EXPECT_EQ(uni->dimensions.rows, 1u);
143  EXPECT_EQ(uni->dimensions.cols, 1u);
144  EXPECT_EQ(uni->location, 10u);
145  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
146  }
147 
148  {
149  auto uni = stage->GetUniform("u_circle1");
150  ASSERT_NE(uni, nullptr);
151  EXPECT_EQ(uni->dimensions.rows, 2u);
152  EXPECT_EQ(uni->dimensions.cols, 1u);
153  EXPECT_EQ(uni->location, 11u);
154  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
155  }
156  {
157  auto uni = stage->GetUniform("u_circle2");
158  ASSERT_NE(uni, nullptr);
159  EXPECT_EQ(uni->dimensions.rows, 2u);
160  EXPECT_EQ(uni->dimensions.cols, 1u);
161  EXPECT_EQ(uni->location, 12u);
162  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
163  }
164  {
165  auto uni = stage->GetUniform("u_circle3");
166  ASSERT_NE(uni, nullptr);
167  EXPECT_EQ(uni->dimensions.rows, 2u);
168  EXPECT_EQ(uni->dimensions.cols, 1u);
169  EXPECT_EQ(uni->location, 13u);
170  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
171  }
172  {
173  auto uni = stage->GetUniform("u_rotation1");
174  ASSERT_NE(uni, nullptr);
175  EXPECT_EQ(uni->dimensions.rows, 2u);
176  EXPECT_EQ(uni->dimensions.cols, 1u);
177  EXPECT_EQ(uni->location, 14u);
178  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
179  }
180  {
181  auto uni = stage->GetUniform("u_rotation2");
182  ASSERT_NE(uni, nullptr);
183  EXPECT_EQ(uni->dimensions.rows, 2u);
184  EXPECT_EQ(uni->dimensions.cols, 1u);
185  EXPECT_EQ(uni->location, 15u);
186  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
187  }
188  {
189  auto uni = stage->GetUniform("u_rotation3");
190  ASSERT_NE(uni, nullptr);
191  EXPECT_EQ(uni->dimensions.rows, 2u);
192  EXPECT_EQ(uni->dimensions.cols, 1u);
193  EXPECT_EQ(uni->location, 16u);
194  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
195  }
196  break;
197  }
198  case PlaygroundBackend::kVulkan: {
199  EXPECT_EQ(stage->GetUniforms().size(), 1u);
200  auto uni = stage->GetUniform(RuntimeStage::kVulkanUBOName);
201  ASSERT_TRUE(uni);
202  EXPECT_EQ(uni->type, RuntimeUniformType::kStruct);
203  EXPECT_EQ(uni->struct_float_count, 32u);
204 
205  // There are 36 4 byte chunks in the UBO: 32 for the 32 floats, and 4 for
206  // padding. Initialize a vector as if they'll all be floats, then manually
207  // set the few padding bytes. If the shader changes, the padding locations
208  // will change as well. For example, if `u_alpha` was moved to the end,
209  // three bytes of padding could potentially be dropped - or if some of the
210  // scalar floats were changed to vec2 or vec4s, or if any vec3s are
211  // introduced.
212  // This means 36 * 4 = 144 bytes total.
213 
214  EXPECT_EQ(uni->GetSize(), 144u);
215  std::vector<uint8_t> layout(uni->GetSize() / sizeof(float), 1);
216  layout[5] = 0;
217  layout[6] = 0;
218  layout[7] = 0;
219  layout[23] = 0;
220 
221  EXPECT_THAT(uni->struct_layout, ::testing::ElementsAreArray(layout));
222  break;
223  }
224  }
225 }

References impeller::RuntimeStage::DecodeRuntimeStages(), impeller::kFloat, impeller::kMetal, impeller::kOpenGLES, impeller::kStruct, impeller::kVulkan, impeller::RuntimeStage::kVulkanUBOName, and impeller::PlaygroundBackendToRuntimeStageBackend().

◆ TEST_P() [404/419]

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

Definition at line 28 of file runtime_stage_unittests.cc.

28  {
29  const std::shared_ptr<fml::Mapping> fixture =
30  flutter::testing::OpenFixtureAsMapping("ink_sparkle.frag.iplr");
31  ASSERT_TRUE(fixture);
32  ASSERT_GT(fixture->GetSize(), 0u);
33  auto stages = RuntimeStage::DecodeRuntimeStages(fixture);
34  auto stage = stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
35  ASSERT_TRUE(stage->IsValid());
36  ASSERT_EQ(stage->GetShaderStage(), RuntimeShaderStage::kFragment);
37 }

References impeller::RuntimeStage::DecodeRuntimeStages(), impeller::kFragment, and impeller::PlaygroundBackendToRuntimeStageBackend().

◆ TEST_P() [405/419]

impeller::testing::TEST_P ( RuntimeStageTest  ,
CanRegisterStage   
)

Definition at line 227 of file runtime_stage_unittests.cc.

227  {
228  const std::shared_ptr<fml::Mapping> fixture =
229  flutter::testing::OpenFixtureAsMapping("ink_sparkle.frag.iplr");
230  ASSERT_TRUE(fixture);
231  ASSERT_GT(fixture->GetSize(), 0u);
232  auto stages = RuntimeStage::DecodeRuntimeStages(fixture);
233  auto stage = stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
234  ASSERT_TRUE(stage->IsValid());
235  std::promise<bool> registration;
236  auto future = registration.get_future();
237  auto library = GetContext()->GetShaderLibrary();
238  library->RegisterFunction(
239  stage->GetEntrypoint(), //
240  ToShaderStage(stage->GetShaderStage()), //
241  stage->GetCodeMapping(), //
242  fml::MakeCopyable([reg = std::move(registration)](bool result) mutable {
243  reg.set_value(result);
244  }));
245  ASSERT_TRUE(future.get());
246  {
247  auto function =
248  library->GetFunction(stage->GetEntrypoint(), ShaderStage::kFragment);
249  ASSERT_NE(function, nullptr);
250  }
251 
252  // Check if unregistering works.
253 
254  library->UnregisterFunction(stage->GetEntrypoint(), ShaderStage::kFragment);
255  {
256  auto function =
257  library->GetFunction(stage->GetEntrypoint(), ShaderStage::kFragment);
258  ASSERT_EQ(function, nullptr);
259  }
260 }

References impeller::RuntimeStage::DecodeRuntimeStages(), impeller::kFragment, impeller::PlaygroundBackendToRuntimeStageBackend(), and impeller::ToShaderStage().

◆ TEST_P() [406/419]

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

Definition at line 39 of file runtime_stage_unittests.cc.

39  {
40  ScopedValidationDisable disable_validation;
41  const std::shared_ptr<fml::Mapping> fixture =
42  flutter::testing::OpenFixtureAsMapping("ink_sparkle.frag.iplr");
43  ASSERT_TRUE(fixture);
44  auto junk_allocation = std::make_shared<Allocation>();
45  ASSERT_TRUE(junk_allocation->Truncate(fixture->GetSize(), false));
46  // Not meant to be secure. Just reject obviously bad blobs using magic
47  // numbers.
48  ::memset(junk_allocation->GetBuffer(), 127, junk_allocation->GetLength());
49  auto stages = RuntimeStage::DecodeRuntimeStages(
50  CreateMappingFromAllocation(junk_allocation));
51  ASSERT_FALSE(stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())]);
52 }

References impeller::CreateMappingFromAllocation(), impeller::RuntimeStage::DecodeRuntimeStages(), and impeller::PlaygroundBackendToRuntimeStageBackend().

◆ TEST_P() [407/419]

impeller::testing::TEST_P ( RuntimeStageTest  ,
ContainsExpectedShaderTypes   
)

Definition at line 305 of file runtime_stage_unittests.cc.

305  {
306  auto stages = OpenAssetAsRuntimeStage("ink_sparkle.frag.iplr");
307  // Right now, SkSL gets implicitly bundled regardless of what the build rule
308  // for this test requested. After
309  // https://github.com/flutter/flutter/issues/138919, this may require a build
310  // rule change or a new test.
311  EXPECT_TRUE(stages[RuntimeStageBackend::kSkSL]);
312 
313  EXPECT_TRUE(stages[RuntimeStageBackend::kOpenGLES]);
314  EXPECT_TRUE(stages[RuntimeStageBackend::kMetal]);
315  EXPECT_TRUE(stages[RuntimeStageBackend::kVulkan]);
316 }

References impeller::kMetal, impeller::kOpenGLES, impeller::kSkSL, and impeller::kVulkan.

◆ TEST_P() [408/419]

impeller::testing::TEST_P ( TypographerTest  ,
CanConvertTextBlob   
)

Definition at line 41 of file typographer_unittests.cc.

41  {
42  SkFont font = flutter::testing::CreateTestFontOfSize(12);
43  auto blob = SkTextBlob::MakeFromString(
44  "the quick brown fox jumped over the lazy dog.", font);
45  ASSERT_TRUE(blob);
46  auto frame = MakeTextFrameFromTextBlobSkia(blob);
47  ASSERT_EQ(frame->GetRunCount(), 1u);
48  for (const auto& run : frame->GetRuns()) {
49  ASSERT_TRUE(run.IsValid());
50  ASSERT_EQ(run.GetGlyphCount(), 45u);
51  }
52 }

References impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [409/419]

impeller::testing::TEST_P ( TypographerTest  ,
CanCreateGlyphAtlas   
)

Definition at line 59 of file typographer_unittests.cc.

59  {
60  auto context = TypographerContextSkia::Make();
61  auto atlas_context = context->CreateGlyphAtlasContext();
62  ASSERT_TRUE(context && context->IsValid());
63  SkFont sk_font = flutter::testing::CreateTestFontOfSize(12);
64  auto blob = SkTextBlob::MakeFromString("hello", sk_font);
65  ASSERT_TRUE(blob);
66  auto atlas = CreateGlyphAtlas(
67  *GetContext(), context.get(), GlyphAtlas::Type::kAlphaBitmap, 1.0f,
68  atlas_context, *MakeTextFrameFromTextBlobSkia(blob));
69  ASSERT_NE(atlas, nullptr);
70  ASSERT_NE(atlas->GetTexture(), nullptr);
71  ASSERT_EQ(atlas->GetType(), GlyphAtlas::Type::kAlphaBitmap);
72  ASSERT_EQ(atlas->GetGlyphCount(), 4llu);
73 
74  std::optional<impeller::ScaledFont> first_scaled_font;
75  std::optional<impeller::Glyph> first_glyph;
76  Rect first_rect;
77  atlas->IterateGlyphs([&](const ScaledFont& scaled_font, const Glyph& glyph,
78  const Rect& rect) -> bool {
79  first_scaled_font = scaled_font;
80  first_glyph = glyph;
81  first_rect = rect;
82  return false;
83  });
84 
85  ASSERT_TRUE(first_scaled_font.has_value());
86  ASSERT_TRUE(atlas
87  ->FindFontGlyphBounds(
88  {first_scaled_font.value(), first_glyph.value()})
89  .has_value());
90 }

References CreateGlyphAtlas(), impeller::GlyphAtlas::kAlphaBitmap, impeller::TypographerContextSkia::Make(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [410/419]

impeller::testing::TEST_P ( TypographerTest  ,
CanCreateRenderContext   
)

Definition at line 54 of file typographer_unittests.cc.

54  {
55  auto context = TypographerContextSkia::Make();
56  ASSERT_TRUE(context && context->IsValid());
57 }

References impeller::TypographerContextSkia::Make().

◆ TEST_P() [411/419]

impeller::testing::TEST_P ( TypographerTest  ,
GlyphAtlasIsRecycledIfUnchanged   
)

Definition at line 147 of file typographer_unittests.cc.

147  {
148  auto context = TypographerContextSkia::Make();
149  auto atlas_context = context->CreateGlyphAtlasContext();
150  ASSERT_TRUE(context && context->IsValid());
151  SkFont sk_font = flutter::testing::CreateTestFontOfSize(12);
152  auto blob = SkTextBlob::MakeFromString("spooky skellingtons", sk_font);
153  ASSERT_TRUE(blob);
154  auto atlas = CreateGlyphAtlas(
155  *GetContext(), context.get(), GlyphAtlas::Type::kAlphaBitmap, 1.0f,
156  atlas_context, *MakeTextFrameFromTextBlobSkia(blob));
157  ASSERT_NE(atlas, nullptr);
158  ASSERT_NE(atlas->GetTexture(), nullptr);
159  ASSERT_EQ(atlas, atlas_context->GetGlyphAtlas());
160 
161  // now attempt to re-create an atlas with the same text blob.
162 
163  auto next_atlas = CreateGlyphAtlas(
164  *GetContext(), context.get(), GlyphAtlas::Type::kAlphaBitmap, 1.0f,
165  atlas_context, *MakeTextFrameFromTextBlobSkia(blob));
166  ASSERT_EQ(atlas, next_atlas);
167  ASSERT_EQ(atlas_context->GetGlyphAtlas(), atlas);
168 }

References CreateGlyphAtlas(), impeller::GlyphAtlas::kAlphaBitmap, impeller::TypographerContextSkia::Make(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [412/419]

impeller::testing::TEST_P ( TypographerTest  ,
GlyphAtlasTextureIsRecreatedIfTypeChanges   
)

Definition at line 247 of file typographer_unittests.cc.

247  {
248  auto context = TypographerContextSkia::Make();
249  auto atlas_context = context->CreateGlyphAtlasContext();
250  ASSERT_TRUE(context && context->IsValid());
251  SkFont sk_font = flutter::testing::CreateTestFontOfSize(12);
252  auto blob = SkTextBlob::MakeFromString("spooky 1", sk_font);
253  ASSERT_TRUE(blob);
254  auto atlas = CreateGlyphAtlas(
255  *GetContext(), context.get(), GlyphAtlas::Type::kAlphaBitmap, 1.0f,
256  atlas_context, *MakeTextFrameFromTextBlobSkia(blob));
257  auto old_packer = atlas_context->GetRectPacker();
258 
259  ASSERT_NE(atlas, nullptr);
260  ASSERT_NE(atlas->GetTexture(), nullptr);
261  ASSERT_EQ(atlas, atlas_context->GetGlyphAtlas());
262 
263  auto* first_texture = atlas->GetTexture().get();
264 
265  // now create a new glyph atlas with an identical blob,
266  // but change the type.
267 
268  auto blob2 = SkTextBlob::MakeFromString("spooky 1", sk_font);
269  auto next_atlas = CreateGlyphAtlas(
270  *GetContext(), context.get(), GlyphAtlas::Type::kColorBitmap, 1.0f,
271  atlas_context, *MakeTextFrameFromTextBlobSkia(blob2));
272  ASSERT_NE(atlas, next_atlas);
273  auto* second_texture = next_atlas->GetTexture().get();
274 
275  auto new_packer = atlas_context->GetRectPacker();
276 
277  ASSERT_NE(second_texture, first_texture);
278  ASSERT_NE(old_packer, new_packer);
279 }

References CreateGlyphAtlas(), impeller::GlyphAtlas::kAlphaBitmap, impeller::GlyphAtlas::kColorBitmap, impeller::TypographerContextSkia::Make(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [413/419]

impeller::testing::TEST_P ( TypographerTest  ,
GlyphAtlasTextureIsRecycledIfUnchanged   
)

Definition at line 214 of file typographer_unittests.cc.

214  {
215  auto context = TypographerContextSkia::Make();
216  auto atlas_context = context->CreateGlyphAtlasContext();
217  ASSERT_TRUE(context && context->IsValid());
218  SkFont sk_font = flutter::testing::CreateTestFontOfSize(12);
219  auto blob = SkTextBlob::MakeFromString("spooky 1", sk_font);
220  ASSERT_TRUE(blob);
221  auto atlas = CreateGlyphAtlas(
222  *GetContext(), context.get(), GlyphAtlas::Type::kAlphaBitmap, 1.0f,
223  atlas_context, *MakeTextFrameFromTextBlobSkia(blob));
224  auto old_packer = atlas_context->GetRectPacker();
225 
226  ASSERT_NE(atlas, nullptr);
227  ASSERT_NE(atlas->GetTexture(), nullptr);
228  ASSERT_EQ(atlas, atlas_context->GetGlyphAtlas());
229 
230  auto* first_texture = atlas->GetTexture().get();
231 
232  // Now create a new glyph atlas with a nearly identical blob.
233 
234  auto blob2 = SkTextBlob::MakeFromString("spooky 2", sk_font);
235  auto next_atlas = CreateGlyphAtlas(
236  *GetContext(), context.get(), GlyphAtlas::Type::kAlphaBitmap, 1.0f,
237  atlas_context, *MakeTextFrameFromTextBlobSkia(blob2));
238  ASSERT_EQ(atlas, next_atlas);
239  auto* second_texture = next_atlas->GetTexture().get();
240 
241  auto new_packer = atlas_context->GetRectPacker();
242 
243  ASSERT_EQ(second_texture, first_texture);
244  ASSERT_EQ(old_packer, new_packer);
245 }

References CreateGlyphAtlas(), impeller::GlyphAtlas::kAlphaBitmap, impeller::TypographerContextSkia::Make(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [414/419]

impeller::testing::TEST_P ( TypographerTest  ,
GlyphAtlasTextureIsRecycledWhenContentsAreNotRecreated   
)

Definition at line 341 of file typographer_unittests.cc.

342  {
343  auto context = TypographerContextSkia::Make();
344  auto atlas_context = context->CreateGlyphAtlasContext();
345  ASSERT_TRUE(context && context->IsValid());
346  SkFont sk_font = flutter::testing::CreateTestFontOfSize(12);
347  auto blob = SkTextBlob::MakeFromString("ABCDEFGHIJKLMNOPQRSTUVQXYZ123456789",
348  sk_font);
349  ASSERT_TRUE(blob);
350  auto atlas = CreateGlyphAtlas(
351  *GetContext(), context.get(), GlyphAtlas::Type::kColorBitmap, 32.0f,
352  atlas_context, *MakeTextFrameFromTextBlobSkia(blob));
353  auto old_packer = atlas_context->GetRectPacker();
354 
355  ASSERT_NE(atlas, nullptr);
356  ASSERT_NE(atlas->GetTexture(), nullptr);
357  ASSERT_EQ(atlas, atlas_context->GetGlyphAtlas());
358 
359  auto* first_texture = atlas->GetTexture().get();
360 
361  // Now create a new glyph atlas with a completely different textblob.
362  // everything should be different except for the underlying atlas texture.
363 
364  auto blob2 = SkTextBlob::MakeFromString("abcdefghijklmnopqrstuvwxyz123456789",
365  sk_font);
366  auto next_atlas = CreateGlyphAtlas(
367  *GetContext(), context.get(), GlyphAtlas::Type::kColorBitmap, 32.0f,
368  atlas_context, *MakeTextFrameFromTextBlobSkia(blob2));
369  ASSERT_NE(atlas, next_atlas);
370  auto* second_texture = next_atlas->GetTexture().get();
371 
372  auto new_packer = atlas_context->GetRectPacker();
373 
374  ASSERT_NE(second_texture, first_texture);
375  ASSERT_NE(old_packer, new_packer);
376 }

References CreateGlyphAtlas(), impeller::GlyphAtlas::kColorBitmap, impeller::TypographerContextSkia::Make(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [415/419]

impeller::testing::TEST_P ( TypographerTest  ,
GlyphAtlasWithLotsOfdUniqueGlyphSize   
)

Definition at line 170 of file typographer_unittests.cc.

170  {
171  auto context = TypographerContextSkia::Make();
172  auto atlas_context = context->CreateGlyphAtlasContext();
173  ASSERT_TRUE(context && context->IsValid());
174 
175  const char* test_string =
176  "QWERTYUIOPASDFGHJKLZXCVBNMqewrtyuiopasdfghjklzxcvbnm,.<>[]{};':"
177  "2134567890-=!@#$%^&*()_+"
178  "œ∑´®†¥¨ˆøπ““‘‘åß∂ƒ©˙∆˚¬…æ≈ç√∫˜µ≤≥≥≥≥÷¡™£¢∞§¶•ªº–≠⁄€‹›fifl‡°·‚—±Œ„´‰Á¨Ø∏”’/"
179  "* Í˝ */¸˛Ç◊ı˜Â¯˘¿";
180 
181  SkFont sk_font = flutter::testing::CreateTestFontOfSize(12);
182  auto blob = SkTextBlob::MakeFromString(test_string, sk_font);
183  ASSERT_TRUE(blob);
184 
185  FontGlyphMap font_glyph_map;
186  size_t size_count = 8;
187  for (size_t index = 0; index < size_count; index += 1) {
188  MakeTextFrameFromTextBlobSkia(blob)->CollectUniqueFontGlyphPairs(
189  font_glyph_map, 0.6 * index);
190  };
191  auto atlas =
192  context->CreateGlyphAtlas(*GetContext(), GlyphAtlas::Type::kAlphaBitmap,
193  atlas_context, font_glyph_map);
194  ASSERT_NE(atlas, nullptr);
195  ASSERT_NE(atlas->GetTexture(), nullptr);
196 
197  std::set<uint16_t> unique_glyphs;
198  std::vector<uint16_t> total_glyphs;
199  atlas->IterateGlyphs(
200  [&](const ScaledFont& scaled_font, const Glyph& glyph, const Rect& rect) {
201  unique_glyphs.insert(glyph.index);
202  total_glyphs.push_back(glyph.index);
203  return true;
204  });
205 
206  EXPECT_EQ(unique_glyphs.size() * size_count, atlas->GetGlyphCount());
207  EXPECT_EQ(total_glyphs.size(), atlas->GetGlyphCount());
208 
209  EXPECT_TRUE(atlas->GetGlyphCount() > 0);
210  EXPECT_TRUE(atlas->GetTexture()->GetSize().width > 0);
211  EXPECT_TRUE(atlas->GetTexture()->GetSize().height > 0);
212 }

References impeller::Glyph::index, impeller::GlyphAtlas::kAlphaBitmap, impeller::TypographerContextSkia::Make(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [416/419]

impeller::testing::TEST_P ( TypographerTest  ,
GlyphAtlasWithOddUniqueGlyphSize   
)

Definition at line 130 of file typographer_unittests.cc.

130  {
131  auto context = TypographerContextSkia::Make();
132  auto atlas_context = context->CreateGlyphAtlasContext();
133  ASSERT_TRUE(context && context->IsValid());
134  SkFont sk_font = flutter::testing::CreateTestFontOfSize(12);
135  auto blob = SkTextBlob::MakeFromString("AGH", sk_font);
136  ASSERT_TRUE(blob);
137  auto atlas = CreateGlyphAtlas(
138  *GetContext(), context.get(), GlyphAtlas::Type::kAlphaBitmap, 1.0f,
139  atlas_context, *MakeTextFrameFromTextBlobSkia(blob));
140  ASSERT_NE(atlas, nullptr);
141  ASSERT_NE(atlas->GetTexture(), nullptr);
142 
143  ASSERT_EQ(atlas->GetTexture()->GetSize().width,
144  atlas->GetTexture()->GetSize().height);
145 }

References CreateGlyphAtlas(), impeller::GlyphAtlas::kAlphaBitmap, impeller::TypographerContextSkia::Make(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [417/419]

impeller::testing::TEST_P ( TypographerTest  ,
LazyAtlasTracksColor   
)

Definition at line 92 of file typographer_unittests.cc.

92  {
93 #if FML_OS_MACOSX
94  auto mapping = flutter::testing::OpenFixtureAsSkData("Apple Color Emoji.ttc");
95 #else
96  auto mapping = flutter::testing::OpenFixtureAsSkData("NotoColorEmoji.ttf");
97 #endif
98  ASSERT_TRUE(mapping);
99  sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
100  SkFont emoji_font(font_mgr->makeFromData(mapping), 50.0);
101  SkFont sk_font = flutter::testing::CreateTestFontOfSize(12);
102 
103  auto blob = SkTextBlob::MakeFromString("hello", sk_font);
104  ASSERT_TRUE(blob);
105  auto frame = MakeTextFrameFromTextBlobSkia(blob);
106 
107  ASSERT_FALSE(frame->GetAtlasType() == GlyphAtlas::Type::kColorBitmap);
108 
109  LazyGlyphAtlas lazy_atlas(TypographerContextSkia::Make());
110 
111  lazy_atlas.AddTextFrame(*frame, 1.0f);
112 
114  SkTextBlob::MakeFromString("😀 ", emoji_font));
115 
116  ASSERT_TRUE(frame->GetAtlasType() == GlyphAtlas::Type::kColorBitmap);
117 
118  lazy_atlas.AddTextFrame(*frame, 1.0f);
119 
120  // Creates different atlases for color and red bitmap.
121  auto color_atlas = lazy_atlas.CreateOrGetGlyphAtlas(
122  *GetContext(), GlyphAtlas::Type::kColorBitmap);
123 
124  auto bitmap_atlas = lazy_atlas.CreateOrGetGlyphAtlas(
125  *GetContext(), GlyphAtlas::Type::kAlphaBitmap);
126 
127  ASSERT_FALSE(color_atlas == bitmap_atlas);
128 }

References impeller::LazyGlyphAtlas::AddTextFrame(), impeller::LazyGlyphAtlas::CreateOrGetGlyphAtlas(), impeller::GlyphAtlas::kAlphaBitmap, impeller::GlyphAtlas::kColorBitmap, impeller::TypographerContextSkia::Make(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [418/419]

impeller::testing::TEST_P ( TypographerTest  ,
MaybeHasOverlapping   
)

Definition at line 281 of file typographer_unittests.cc.

281  {
282  sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
283  sk_sp<SkTypeface> typeface =
284  font_mgr->matchFamilyStyle("Arial", SkFontStyle::Normal());
285  SkFont sk_font(typeface, 0.5f);
286 
287  auto frame =
288  MakeTextFrameFromTextBlobSkia(SkTextBlob::MakeFromString("1", sk_font));
289  // Single character has no overlapping
290  ASSERT_FALSE(frame->MaybeHasOverlapping());
291 
292  auto frame_2 = MakeTextFrameFromTextBlobSkia(
293  SkTextBlob::MakeFromString("123456789", sk_font));
294  ASSERT_FALSE(frame_2->MaybeHasOverlapping());
295 }

References impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [419/419]

impeller::testing::TEST_P ( TypographerTest  ,
RectanglePackerAddsNonoverlapingRectangles   
)

Definition at line 297 of file typographer_unittests.cc.

297  {
298  auto packer = RectanglePacker::Factory(200, 100);
299  ASSERT_NE(packer, nullptr);
300  ASSERT_EQ(packer->percentFull(), 0);
301 
302  const SkIRect packer_area = SkIRect::MakeXYWH(0, 0, 200, 100);
303 
304  IPoint16 first_output = {-1, -1}; // Fill with sentinel values
305  ASSERT_TRUE(packer->addRect(20, 20, &first_output));
306  // Make sure the rectangle is placed such that it is inside the bounds of
307  // the packer's area.
308  const SkIRect first_rect =
309  SkIRect::MakeXYWH(first_output.x(), first_output.y(), 20, 20);
310  ASSERT_TRUE(SkIRect::Intersects(packer_area, first_rect));
311 
312  // Initial area was 200 x 100 = 20_000
313  // We added 20x20 = 400. 400 / 20_000 == 0.02 == 2%
314  ASSERT_TRUE(flutter::testing::NumberNear(packer->percentFull(), 0.02));
315 
316  IPoint16 second_output = {-1, -1};
317  ASSERT_TRUE(packer->addRect(140, 90, &second_output));
318  const SkIRect second_rect =
319  SkIRect::MakeXYWH(second_output.x(), second_output.y(), 140, 90);
320  // Make sure the rectangle is placed such that it is inside the bounds of
321  // the packer's area but not in the are of the first rectangle.
322  ASSERT_TRUE(SkIRect::Intersects(packer_area, second_rect));
323  ASSERT_FALSE(SkIRect::Intersects(first_rect, second_rect));
324 
325  // We added another 90 x 140 = 12_600 units, now taking us to 13_000
326  // 13_000 / 20_000 == 0.65 == 65%
327  ASSERT_TRUE(flutter::testing::NumberNear(packer->percentFull(), 0.65));
328 
329  // There's enough area to add this rectangle, but no space big enough for
330  // the 50 units of width.
331  IPoint16 output;
332  ASSERT_FALSE(packer->addRect(50, 50, &output));
333  // Should be unchanged.
334  ASSERT_TRUE(flutter::testing::NumberNear(packer->percentFull(), 0.65));
335 
336  packer->reset();
337  // Should be empty now.
338  ASSERT_EQ(packer->percentFull(), 0);
339 }

References impeller::RectanglePacker::Factory(), NumberNear(), impeller::IPoint16::x(), and impeller::IPoint16::y().

◆ toColor()

flutter::DlColor impeller::testing::toColor ( const float *  components)

Definition at line 41 of file dl_unittests.cc.

41  {
42  return flutter::DlColor(Color::ToIColor(
43  Color(components[0], components[1], components[2], components[3])));
44 }

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 16 of file golden_paths.h.

Referenced by TEST_P().

◆ kFontFixture

constexpr std::string_view impeller::testing::kFontFixture
staticconstexpr
Initial value:
=
"NotoColorEmoji.ttf"

Definition at line 857 of file aiks_unittests.cc.

Referenced by TEST_P().

◆ kPaintVariations

const std::map<std::string, MaskBlurTestConfig> impeller::testing::kPaintVariations
static

Definition at line 368 of file aiks_blur_unittests.cc.

_BLEND_MODE_RESULT_CHECK
#define _BLEND_MODE_RESULT_CHECK(blend_mode)
Definition: geometry_unittests.cc:1579
NumberNear
bool NumberNear(double a, double b)
Definition: geometry_asserts.h:18
ASSERT_COLOR_NEAR
#define ASSERT_COLOR_NEAR(a, b)
Definition: geometry_asserts.h:159
impeller::kFloat
@ kFloat
Definition: runtime_types.h:23
impeller::kResetTransform
@ kResetTransform
Definition: canvas_recorder.h:25
impeller::OptionsFromPass
ContentContextOptions OptionsFromPass(const RenderPass &pass)
Definition: contents.cc:20
impeller::k1OverSqrt2
constexpr float k1OverSqrt2
Definition: constants.h:50
impeller::kPreConcat
@ kPreConcat
Definition: canvas_recorder.h:28
impeller::kDrawImage
@ kDrawImage
Definition: canvas_recorder.h:42
impeller::testing::CompareFunctionUI
static const CompareFunctionUIData & CompareFunctionUI()
Definition: renderer_unittests.cc:1111
impeller::MyMask
Mask< MyMaskBits > MyMask
Definition: base_unittests.cc:20
impeller::BlendModeToString
const char * BlendModeToString(BlendMode blend_mode)
Definition: color.cc:47
impeller::kClipPath
@ kClipPath
Definition: canvas_recorder.h:44
polyline
const Path::Polyline & polyline
Definition: stroke_path_geometry.cc:292
impeller::kClipOval
@ kClipOval
Definition: canvas_recorder.h:46
impeller::TPoint::y
Type y
Definition: point.h:31
impeller::Scalar
float Scalar
Definition: scalar.h:18
impeller::TPoint::Ceil
constexpr TPoint Ceil() const
Definition: point.h:196
impeller::testing::CompareFunctionUIData::IndexOf
int IndexOf(CompareFunction func) const
Definition: renderer_unittests.cc:1094
impeller::testing::CanRenderSweepGradientWithDithering
static void CanRenderSweepGradientWithDithering(AiksTest *aiks_test, bool use_dithering)
Definition: aiks_gradient_unittests.cc:137
impeller::kConcat
@ kConcat
Definition: canvas_recorder.h:27
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:198
impeller::testing::swap_nan
static constexpr Point swap_nan(const Point &point, int index)
Definition: rect_unittests.cc:1305
impeller::skia_conversions::ToSize
Size ToSize(const SkPoint &point)
Definition: skia_conversions.cc:144
impeller::BlendMode
BlendMode
Definition: color.h:59
impeller::testing::CreateMappingFromString
static std::shared_ptr< fml::Mapping > CreateMappingFromString(std::string p_string)
Definition: shader_archive_unittests.cc:20
impeller::TPoint::Lerp
constexpr TPoint Lerp(const TPoint &p, Scalar t) const
Definition: point.h:230
impeller::kEhCloseEnough
constexpr float kEhCloseEnough
Definition: constants.h:56
impeller::TextureDescriptor::format
PixelFormat format
Definition: texture_descriptor.h:40
impeller::testing::CanRenderConicalGradientWithDithering
static void CanRenderConicalGradientWithDithering(AiksTest *aiks_test, bool use_dithering)
Definition: aiks_gradient_unittests.cc:166
EXPECT_SOLID_VERTICES_NEAR
#define EXPECT_SOLID_VERTICES_NEAR(a, b)
Definition: geometry_unittests.cc:45
impeller::TPoint::Min
constexpr TPoint Min(const TPoint &p) const
Definition: point.h:186
impeller::kRotate
@ kRotate
Definition: canvas_recorder.h:33
impeller::TPoint::Round
static constexpr TPoint Round(const TPoint< U > &other)
Definition: point.h:49
impeller::Vector2
Point Vector2
Definition: point.h:320
EXPECT_POINT_NEAR
#define EXPECT_POINT_NEAR(a, b)
Definition: geometry_asserts.h:172
MatrixNear
inline ::testing::AssertionResult MatrixNear(impeller::Matrix a, impeller::Matrix b)
Definition: geometry_asserts.h:23
impeller::kPi
constexpr float kPi
Definition: constants.h:26
BLEND_MODE_TUPLE
#define BLEND_MODE_TUPLE(blend_mode)
Definition: aiks_unittests.cc:1033
impeller::testing::flip_lrtb
static constexpr R flip_lrtb(R rect)
Definition: rect_unittests.cc:1291
impeller::CreateTextureFromDrawableFuture
std::shared_ptr< TextureMTL > CreateTextureFromDrawableFuture(TextureDescriptor desc, const std::shared_future< id< CAMetalDrawable >> &drawble_future)
Create a TextureMTL from a deferred drawable.
Definition: lazy_drawable_holder.mm:41
impeller::skia_conversions::ToColor
Color ToColor(const flutter::DlColor &color)
Definition: skia_conversions.cc:148
impeller::FontGlyphMap
std::unordered_map< ScaledFont, std::unordered_set< Glyph > > FontGlyphMap
Definition: font_glyph_pair.h:29
impeller::UintPoint32
TPoint< uint32_t > UintPoint32
Definition: point.h:319
impeller::testing::golden_cubic_and_quad_points
std::vector< Point > golden_cubic_and_quad_points
Definition: golden_paths.h:16
impeller::Size
TSize< Scalar > Size
Definition: size.h:137
impeller::StorageMode::kHostVisible
@ kHostVisible
ASSERT_POINT_NEAR
#define ASSERT_POINT_NEAR(a, b)
Definition: geometry_asserts.h:160
impeller::GenerateBlurInfo
KernelPipeline::FragmentShader::KernelSamples GenerateBlurInfo(BlurParameters parameters)
Definition: gaussian_blur_filter_contents.cc:586
impeller::CreateMappingFromAllocation
std::shared_ptr< fml::Mapping > CreateMappingFromAllocation(const std::shared_ptr< Allocation > &allocation)
Definition: allocation.cc:99
ASSERT_VECTOR4_NEAR
#define ASSERT_VECTOR4_NEAR(a, b)
Definition: geometry_asserts.h:162
impeller::PlaygroundBackendToRuntimeStageBackend
constexpr RuntimeStageBackend PlaygroundBackendToRuntimeStageBackend(PlaygroundBackend backend)
Definition: playground.h:35
impeller::kSave
@ kSave
Definition: canvas_recorder.h:21
stroke_width
const Scalar stroke_width
Definition: stroke_path_geometry.cc:293
impeller::MoveTo
void MoveTo(PathBuilder *builder, Scalar x, Scalar y)
Definition: tessellator.cc:18
EXPECT_RECT_NEAR
#define EXPECT_RECT_NEAR(a, b)
Definition: geometry_asserts.h:170
impeller::GetDrawableDeferred
std::shared_future< id< CAMetalDrawable > > GetDrawableDeferred(CAMetalLayer *layer)
Create a deferred drawable from a CAMetalLayer.
Definition: lazy_drawable_holder.mm:23
impeller::TPoint::Floor
constexpr TPoint Floor() const
Definition: point.h:194
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:751
impeller::kPiOver2
constexpr float kPiOver2
Definition: constants.h:32
impeller::LerpHackKernelSamples
KernelPipeline::FragmentShader::KernelSamples LerpHackKernelSamples(KernelPipeline::FragmentShader::KernelSamples parameters)
Definition: gaussian_blur_filter_contents.cc:622
impeller::PixelFormat
PixelFormat
The Pixel formats supported by Impeller. The naming convention denotes the usage of the component,...
Definition: formats.h:100
ASSERT_RECT_NEAR
#define ASSERT_RECT_NEAR(a, b)
Definition: geometry_asserts.h:158
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::kDrawCircle
@ kDrawCircle
Definition: canvas_recorder.h:40
impeller::kPhi
constexpr float kPhi
Definition: constants.h:53
impeller::VS
SolidFillVertexShader VS
Definition: stroke_path_geometry.cc:15
impeller::kColor
@ kColor
Definition: geometry.h:51
impeller::saturated::distance
SI distance
Definition: saturated_math.h:57
impeller::testing::toColor
flutter::DlColor toColor(const float *components)
Definition: dl_unittests.cc:41
impeller::kDrawTextFrame
@ kDrawTextFrame
Definition: canvas_recorder.h:48
impeller::testing::CreateColorVertices
std::shared_ptr< VerticesGeometry > CreateColorVertices(const std::vector< Point > &vertices, const std::vector< Color > &colors)
Definition: vertices_contents_unittests.cc:26
impeller::kScale2
@ kScale2
Definition: canvas_recorder.h:30
impeller::Point
TPoint< Scalar > Point
Definition: point.h:316
impeller::k2Pi
constexpr float k2Pi
Definition: constants.h:29
impeller::Quad
std::array< Point, 4 > Quad
Definition: point.h:321
impeller::testing::CompareFunctionUIData::FunctionOf
CompareFunction FunctionOf(int index) const
Definition: renderer_unittests.cc:1104
impeller::testing::RGBToYUV
static Vector3 RGBToYUV(Vector3 rgb, YUVColorSpace yuv_color_space)
Definition: entity_unittests.cc:2093
impeller::MipFilter
MipFilter
Definition: formats.h:415
impeller::testing::flip_lr
static constexpr R flip_lr(R rect)
Definition: rect_unittests.cc:1279
impeller::SPrintF
std::string SPrintF(const char *format,...)
Definition: strings.cc:12
impeller::testing::GetBlendModeSelection
static BlendModeSelection GetBlendModeSelection()
Definition: aiks_unittests.cc:1040
impeller::IPoint32
TPoint< int32_t > IPoint32
Definition: point.h:318
impeller::ScalarToHalf
constexpr InternalHalf ScalarToHalf(Scalar f)
Convert a scalar to a half precision float.
Definition: half.h:32
EXPECT_TEXTURE_VERTICES_NEAR
#define EXPECT_TEXTURE_VERTICES_NEAR(a, b)
Definition: geometry_unittests.cc:47
impeller::kDrawRect
@ kDrawRect
Definition: canvas_recorder.h:37
impeller::TPoint::Max
constexpr TPoint Max(const TPoint &p) const
Definition: point.h:190
impeller::testing::CreatePassWithRectPath
auto CreatePassWithRectPath(Rect rect, std::optional< Rect > bounds_hint, ContentBoundsPromise bounds_promise=ContentBoundsPromise::kUnknown, bool collapse=false)
Definition: entity_unittests.cc:109
impeller::testing::CanRenderRadialGradientWithDithering
static void CanRenderRadialGradientWithDithering(AiksTest *aiks_test, bool use_dithering)
Definition: aiks_gradient_unittests.cc:110
impeller::kSkew
@ kSkew
Definition: canvas_recorder.h:32
impeller::kClipRRect
@ kClipRRect
Definition: canvas_recorder.h:47
impeller::MinMagFilter
MinMagFilter
Definition: formats.h:407
impeller::kDrawImageRect
@ kDrawImageRect
Definition: canvas_recorder.h:43
impeller::testing::CanRenderLinearGradientWithDithering
static void CanRenderLinearGradientWithDithering(AiksTest *aiks_test, bool use_dithering)
Definition: aiks_gradient_unittests.cc:82
impeller::testing::CreateTestYUVTextures
static std::vector< std::shared_ptr< Texture > > CreateTestYUVTextures(Context *context, YUVColorSpace yuv_color_space)
Definition: entity_unittests.cc:2110
_BLEND_MODE_NAME_CHECK
#define _BLEND_MODE_NAME_CHECK(blend_mode)
Definition: geometry_unittests.cc:1598
impeller::Rect
TRect< Scalar > Rect
Definition: rect.h:661
ASSERT_MATRIX_NEAR
#define ASSERT_MATRIX_NEAR(a, b)
Definition: geometry_asserts.h:156
impeller::testing::CreateStringFromMapping
const std::string CreateStringFromMapping(const fml::Mapping &mapping)
Definition: shader_archive_unittests.cc:28
impeller::TextureUsageMask
Mask< TextureUsage > TextureUsageMask
Definition: formats.h:309
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::kStruct
@ kStruct
Definition: runtime_types.h:25
impeller::kTransform
@ kTransform
Definition: canvas_recorder.h:26
impeller::kDrawAtlas
@ kDrawAtlas
Definition: canvas_recorder.h:50
impeller::skia_conversions::ToPoint
Point ToPoint(const SkPoint &point)
Definition: skia_conversions.cc:140
IMPELLER_FOR_EACH_BLEND_MODE
#define IMPELLER_FOR_EACH_BLEND_MODE(V)
Definition: color.h:19
IMPELLER_RAND
#define IMPELLER_RAND
Definition: gaussian_blur_filter_contents_unittests.cc:17
impeller::IRect
TRect< int64_t > IRect
Definition: rect.h:662
impeller::MakeTextFrameFromTextBlobSkia
std::shared_ptr< TextFrame > MakeTextFrameFromTextBlobSkia(const sk_sp< SkTextBlob > &blob)
Definition: text_frame_skia.cc:41
impeller::kDrawPaint
@ kDrawPaint
Definition: canvas_recorder.h:35
impeller::ToMTLPixelFormat
constexpr MTLPixelFormat ToMTLPixelFormat(PixelFormat format)
Definition: formats_mtl.h:77
ASSERT_QUATERNION_NEAR
#define ASSERT_QUATERNION_NEAR(a, b)
Definition: geometry_asserts.h:157
impeller::Close
void Close(PathBuilder *builder)
Definition: tessellator.cc:36
impeller::ISize
TSize< int64_t > ISize
Definition: size.h:138
impeller::kSaveLayer
@ kSaveLayer
Definition: canvas_recorder.h:22
impeller::TextureDescriptor::size
ISize size
Definition: texture_descriptor.h:41
VALIDATION_LOG
#define VALIDATION_LOG
Definition: validation.h:73
impeller::testing::RenderTextInCanvasSkia
bool RenderTextInCanvasSkia(const std::shared_ptr< Context > &context, Canvas &canvas, const std::string &text, const std::string_view &font_fixture, TextRenderOptions options={})
Definition: aiks_unittests.cc:714
impeller::LineTo
void LineTo(PathBuilder *builder, Scalar x, Scalar y)
Definition: tessellator.cc:22
impeller::Join
Join
Definition: path.h:23
textures
std::vector< std::shared_ptr< FakeTexture > > textures
Definition: content_context_unittests.cc:92
RectNear
inline ::testing::AssertionResult RectNear(impeller::Rect a, impeller::Rect b)
Definition: geometry_asserts.h:56
impeller::DrawPlaygroundPoint
Point DrawPlaygroundPoint(PlaygroundPoint &point)
Definition: widgets.cc:9
impeller::kDrawPoints
@ kDrawPoints
Definition: canvas_recorder.h:41
impeller::IPoint
TPoint< int64_t > IPoint
Definition: point.h:317
impeller::MyMaskBits
MyMaskBits
Definition: base_unittests.cc:13
ASSERT_VECTOR3_NEAR
#define ASSERT_VECTOR3_NEAR(a, b)
Definition: geometry_asserts.h:161
FLT_FORWARD
#define FLT_FORWARD(mock, real, method)
Definition: aiks_blur_unittests.cc:489
impeller::saturated::b
SI b
Definition: saturated_math.h:87
impeller::testing::kFontFixture
static constexpr std::string_view kFontFixture
Definition: aiks_unittests.cc:857
scale
const Scalar scale
Definition: stroke_path_geometry.cc:297
impeller::ScalarNearlyEqual
constexpr bool ScalarNearlyEqual(Scalar x, Scalar y, Scalar tolerance=kEhCloseEnough)
Definition: scalar.h:30
impeller::YUVColorSpace
YUVColorSpace
Definition: color.h:55
impeller::kDrawOval
@ kDrawOval
Definition: canvas_recorder.h:38
impeller::SampleCount::kCount1
@ kCount1
impeller::TextureDescriptor::storage_mode
StorageMode storage_mode
Definition: texture_descriptor.h:38
impeller::kScale3
@ kScale3
Definition: canvas_recorder.h:31
impeller::TPoint::GetDistance
constexpr Type GetDistance(const TPoint &p) const
Definition: point.h:200
impeller::TextureDescriptor
A lightweight object that describes the attributes of a texture that can then used an allocator to cr...
Definition: texture_descriptor.h:37
offset
Point offset
Definition: stroke_path_geometry.cc:300
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:28
impeller::TSize::MipCount
constexpr size_t MipCount() const
Definition: size.h:115
impeller::kDrawVertices
@ kDrawVertices
Definition: canvas_recorder.h:49
impeller::TPoint::Normalize
constexpr TPoint Normalize() const
Definition: point.h:208
impeller::kDrawLine
@ kDrawLine
Definition: canvas_recorder.h:36
impeller::testing::flip_tb
static constexpr R flip_tb(R rect)
Definition: rect_unittests.cc:1285
impeller::kDrawPath
@ kDrawPath
Definition: canvas_recorder.h:34
impeller::kDrawRRect
@ kDrawRRect
Definition: canvas_recorder.h:39
ASSERT_COLOR_BUFFER_NEAR
#define ASSERT_COLOR_BUFFER_NEAR(a, b)
Definition: geometry_asserts.h:165
impeller::kRestore
@ kRestore
Definition: canvas_recorder.h:23
impeller::kPiOver4
constexpr float kPiOver4
Definition: constants.h:35
impeller::skia_conversions::ToPath
Path ToPath(const SkPath &path, Point shift)
Definition: skia_conversions.cc:49
impeller::kTranslate
@ kTranslate
Definition: canvas_recorder.h:29
impeller::kClipRect
@ kClipRect
Definition: canvas_recorder.h:45
impeller::Cap
Cap
Definition: path.h:17
ASSERT_ARRAY_4_NEAR
#define ASSERT_ARRAY_4_NEAR(a, b)
Definition: geometry_asserts.h:164
IPLR_REQUIRES
#define IPLR_REQUIRES(...)
Definition: thread_safety.h:30
impeller::DrawPlaygroundLine
std::tuple< Point, Point > DrawPlaygroundLine(PlaygroundPoint &point_a, PlaygroundPoint &point_b)
Definition: widgets.cc:50
impeller::kRestoreToCount
@ kRestoreToCount
Definition: canvas_recorder.h:24