Flutter Impeller
impeller::testing Namespace Reference

Classes

class  ArchivistFixture
 
struct  BlendModeSelection
 
class  CompareFunctionUIData
 
struct  CVTest
 
class  DirectionalGaussianBlurFilterContentsTest
 
struct  Foo
 
class  GaussianBlurFilterContentsTest
 
class  GoldenDigest
 Manages a global variable for tracking instances of golden images. More...
 
class  GoldenTests
 
class  MetalScreenshot
 A screenshot that was produced from MetalScreenshotter. More...
 
class  MetalScreenshotter
 
class  RendererDartTest
 
struct  RWFoo
 
class  Sample
 
class  SampleWithVector
 
class  TestAllocator
 
class  TestPassDelegate
 
class  TestRenderTargetAllocator
 
struct  TextRenderOptions
 
class  WorkingDirectory
 

Typedefs

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

Functions

 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)
 
 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, CanRenderTiledTextureClamp)
 
 TEST_P (AiksTest, CanRenderTiledTextureClampAsync)
 
 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, 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 (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, CanRenderMaskBlurHugeSigma)
 
 TEST_P (AiksTest, CanRenderBackdropBlurInteractive)
 
 TEST_P (AiksTest, CanRenderBackdropBlur)
 
 TEST_P (AiksTest, CanRenderBackdropBlurHugeSigma)
 
 TEST_P (AiksTest, CanRenderClippedBlur)
 
 TEST_P (AiksTest, CanRenderForegroundBlendWithMaskBlur)
 
 TEST_P (AiksTest, CanRenderForegroundAdvancedBlendWithMaskBlur)
 
 TEST_P (AiksTest, CanRenderClippedRuntimeEffects)
 
 TEST_P (AiksTest, DrawPaintTransformsBounds)
 
 TEST_P (AiksTest, CanDrawPoints)
 
 TEST_P (AiksTest, DrawAtlasWithColorAdvancedAndTransform)
 
 TEST_P (AiksTest, DrawAtlasAdvancedAndTransform)
 
 TEST_P (AiksTest, CanDrawPointsWithTextureMap)
 
 TEST_P (AiksTest, TextForegroundShaderWithTransform)
 
 TEST_P (AiksTest, CanCanvasDrawPicture)
 
 TEST_P (AiksTest, CanCanvasDrawPictureWithAdvancedBlend)
 
 TEST_P (AiksTest, CanCanvasDrawPictureWithBackdropFilter)
 
 TEST_P (AiksTest, DrawPictureWithText)
 
 TEST_P (AiksTest, DrawPictureClipped)
 
 TEST_P (AiksTest, MatrixSaveLayerFilter)
 
 TEST_P (AiksTest, MatrixBackdropFilter)
 
 TEST_P (AiksTest, SolidColorApplyColorFilter)
 
 TEST_P (AiksTest, DrawScaledTextWithPerspectiveNoSaveLayer)
 
 TEST_P (AiksTest, DrawScaledTextWithPerspectiveSaveLayer)
 
 TEST_P (AiksTest, PipelineBlendSingleParameter)
 
 TEST_P (AiksTest, ClippedBlurFilterRendersCorrectlyInteractive)
 
 TEST_P (AiksTest, ClippedBlurFilterRendersCorrectly)
 
 TEST_P (AiksTest, CaptureContext)
 
 TEST_P (AiksTest, CaptureInactivatedByDefault)
 
 TEST_P (AiksTest, ReleasesTextureOnTeardown)
 
 TEST_P (AiksTest, VerticesGeometryUVPositionData)
 
 TEST_P (AiksTest, VerticesGeometryUVPositionDataWithTranslate)
 
 TEST_P (AiksTest, ClearBlendWithBlur)
 
 TEST_P (AiksTest, ClearBlend)
 
 TEST_P (AiksTest, MatrixImageFilterMagnify)
 
 TEST_P (AiksTest, MatrixImageFilterDoesntCullWhenTranslatedFromOffscreen)
 
 TEST_P (AiksTest, MatrixImageFilterDoesntCullWhenScaledAndTranslatedFromOffscreen)
 
 TEST_P (AiksTest, ClearColorOptimizationWhenSubpassIsBiggerThanParentPass)
 
 TEST_P (AiksTest, BlurHasNoEdge)
 
 TEST_P (AiksTest, EmptySaveLayerIgnoresPaint)
 
 TEST_P (AiksTest, EmptySaveLayerRendersWithClear)
 
 TEST_P (AiksTest, BlurredRectangleWithShader)
 
 TEST_P (AiksTest, MaskBlurWithZeroSigmaIsSkipped)
 
 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, SubpassWithClearColorOptimization)
 
 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, DrawRect)
 
 TEST (CanvasRecorder, DrawRRect)
 
 TEST (CanvasRecorder, DrawCircle)
 
 TEST (CanvasRecorder, DrawPoints)
 
 TEST (CanvasRecorder, DrawImage)
 
 TEST (CanvasRecorder, DrawImageRect)
 
 TEST (CanvasRecorder, ClipPath)
 
 TEST (CanvasRecorder, ClipRect)
 
 TEST (CanvasRecorder, ClipRRect)
 
 TEST (CanvasRecorder, DrawPicture)
 
 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_F (ArchiveTest, SimpleInitialization)
 
 TEST_F (ArchiveTest, AddStorageClass)
 
 TEST_F (ArchiveTest, AddData)
 
 TEST_F (ArchiveTest, AddDataMultiple)
 
 TEST_F (ArchiveTest, ReadData)
 
 TEST_F (ArchiveTest, ReadDataWithNames)
 
 TEST_F (ArchiveTest, CanReadWriteVectorOfArchivables)
 
 TEST (ThreadTest, CanCreateMutex)
 
 TEST (ThreadTest, CanCreateMutexLock)
 
 TEST (ThreadTest, CanCreateRWMutex)
 
 TEST (ThreadTest, CanCreateRWMutexLock)
 
 TEST (StringsTest, CanSPrintF)
 
 TEST (ConditionVariableTest, WaitUntil)
 
 TEST (ConditionVariableTest, WaitFor)
 
 TEST (ConditionVariableTest, WaitForever)
 
 TEST (ConditionVariableTest, TestsCriticalSectionAfterWaitForUntil)
 
 TEST (ConditionVariableTest, TestsCriticalSectionAfterWait)
 
 TEST (AllocatorTest, TextureDescriptorCompatibility)
 
flutter::DlColor toColor (const float *components)
 
 INSTANTIATE_PLAYGROUND_SUITE (DisplayListTest)
 
 TEST_P (DisplayListTest, DrawPictureWithAClip)
 
 TEST_P (DisplayListTest, CanDrawRect)
 
 TEST_P (DisplayListTest, CanDrawTextBlob)
 
 TEST_P (DisplayListTest, CanDrawTextBlobWithGradient)
 
 TEST_P (DisplayListTest, CanDrawTextWithSaveLayer)
 
 TEST_P (DisplayListTest, CanDrawImage)
 
 TEST_P (DisplayListTest, CanDrawCapsAndJoins)
 
 TEST_P (DisplayListTest, CanDrawArc)
 
 TEST_P (DisplayListTest, StrokedPathsDrawCorrectly)
 
 TEST_P (DisplayListTest, CanDrawWithOddPathWinding)
 
 TEST_P (DisplayListTest, CanDrawAnOpenPath)
 
 TEST_P (DisplayListTest, CanDrawWithMaskBlur)
 
 TEST_P (DisplayListTest, CanDrawStrokedText)
 
 TEST_P (DisplayListTest, StrokedTextNotOffsetFromNormalText)
 
 TEST_P (DisplayListTest, IgnoreMaskFilterWhenSavingLayer)
 
 TEST_P (DisplayListTest, CanDrawWithBlendColorFilter)
 
 TEST_P (DisplayListTest, CanDrawWithColorFilterImageFilter)
 
 TEST_P (DisplayListTest, CanDrawWithImageBlurFilter)
 
 TEST_P (DisplayListTest, CanDrawWithComposeImageFilter)
 
 TEST_P (DisplayListTest, CanClampTheResultingColorOfColorMatrixFilter)
 
 TEST_P (DisplayListTest, CanDrawBackdropFilter)
 
 TEST_P (DisplayListTest, CanDrawNinePatchImage)
 
 TEST_P (DisplayListTest, CanDrawNinePatchImageCenterWidthBiggerThanDest)
 
 TEST_P (DisplayListTest, CanDrawNinePatchImageCenterHeightBiggerThanDest)
 
 TEST_P (DisplayListTest, CanDrawNinePatchImageCenterBiggerThanDest)
 
 TEST_P (DisplayListTest, CanDrawNinePatchImageCornersScaledDown)
 
 TEST_P (DisplayListTest, CanDrawPoints)
 
 TEST_P (DisplayListTest, CanDrawZeroLengthLine)
 
 TEST_P (DisplayListTest, CanDrawShadow)
 
 TEST_P (DisplayListTest, DispatcherDoesNotCullPerspectiveTransformedChildDisplayLists)
 
 TEST_P (DisplayListTest, TransparentShadowProducesCorrectColor)
 
 TEST_P (DisplayListTest, CanConvertTriangleFanToTriangles)
 
 TEST_P (DisplayListTest, CanDrawZeroWidthLine)
 
 TEST_P (DisplayListTest, CanDrawWithMatrixFilter)
 
 TEST_P (DisplayListTest, CanDrawWithMatrixFilterWhenSavingLayer)
 
 TEST_P (DisplayListTest, CanDrawRectWithLinearToSrgbColorFilter)
 
 TEST_P (DisplayListTest, CanDrawPaintWithColorSource)
 
 TEST_P (DisplayListTest, CanBlendDstOverAndDstCorrectly)
 
 TEST_P (DisplayListTest, CanDrawCorrectlyWithColorFilterAndImageFilter)
 
 TEST_P (DisplayListTest, MaskBlursApplyCorrectlyToColorSources)
 
 TEST_P (DisplayListTest, DrawVerticesSolidColorTrianglesWithoutIndices)
 
 TEST_P (DisplayListTest, DrawVerticesLinearGradientWithoutIndices)
 
 TEST_P (DisplayListTest, DrawVerticesLinearGradientWithTextureCoordinates)
 
 TEST_P (DisplayListTest, DrawVerticesImageSourceWithTextureCoordinates)
 
 TEST_P (DisplayListTest, DrawVerticesImageSourceWithTextureCoordinatesAndColorBlending)
 
 TEST_P (DisplayListTest, DrawVerticesSolidColorTrianglesWithIndices)
 
 TEST_P (DisplayListTest, DrawVerticesPremultipliesColors)
 
 TEST_P (DisplayListTest, DrawShapes)
 
 TEST_P (DisplayListTest, ClipDrawRRectWithNonCircularRadii)
 
 TEST_P (DisplayListTest, DrawVerticesBlendModes)
 
template<typename Contents >
static std::optional< RectGetCoverageOfFirstEntity (const Picture &picture)
 
 TEST (DisplayListTest, RRectBoundsComputation)
 
 TEST (DisplayListTest, CircleBoundsComputation)
 
 TEST (SkiaConversionsTest, SkPointToPoint)
 
 TEST (SkiaConversionsTest, SkPointToSize)
 
 TEST (SkiaConversionsTest, ToColor)
 
 TEST (SkiaConversionsTest, GradientStopConversion)
 
 TEST (SkiaConversionsTest, GradientMissing0)
 
 TEST (SkiaConversionsTest, GradientMissingLastValue)
 
 TEST (SkiaConversionsTest, GradientStopGreaterThan1)
 
 TEST (SkiaConversionsTest, GradientConversionNonMonotonic)
 
 INSTANTIATE_PLAYGROUND_SUITE (DirectionalGaussianBlurFilterContentsTest)
 
 TEST_P (DirectionalGaussianBlurFilterContentsTest, CoverageWithEffectTransform)
 
 TEST (DirectionalGaussianBlurFilterContentsTest, FilterSourceCoverage)
 
 TEST_P (DirectionalGaussianBlurFilterContentsTest, RenderNoCoverage)
 
 TEST_P (DirectionalGaussianBlurFilterContentsTest, RenderCoverageMatchesGetCoverage)
 
 TEST_P (DirectionalGaussianBlurFilterContentsTest, TextureContentsWithDestinationRect)
 
 TEST_P (DirectionalGaussianBlurFilterContentsTest, TextureContentsWithDestinationRectScaled)
 
 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 (GaussianBlurFilterContentsTest, CalculateSigmaForBlurRadius)
 
 TEST (GaussianBlurFilterContentsTest, Coefficients)
 
 TEST (FilterInputTest, CanSetLocalTransformForTexture)
 
 TEST (FilterInputTest, IsLeaf)
 
 TEST (FilterInputTest, SetCoverageInputs)
 
 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)
 
 INSTANTIATE_PLAYGROUND_SUITE (EntityPassTargetTest)
 
 TEST_P (EntityPassTargetTest, SwapWithMSAATexture)
 
 TEST_P (EntityPassTargetTest, SwapWithMSAAImplicitResolve)
 
 TEST_P (EntityTest, CanCreateEntity)
 
auto CreatePassWithRectPath (Rect rect, std::optional< Rect > bounds_hint, bool collapse=false)
 
 TEST_P (EntityTest, EntityPassRespectsSubpassBoundsLimit)
 
 TEST_P (EntityTest, EntityPassCanMergeSubpassIntoParent)
 
 TEST_P (EntityTest, EntityPassCoverageRespectsCoverageLimit)
 
 TEST_P (EntityTest, FilterCoverageRespectsCropRect)
 
 TEST_P (EntityTest, CanDrawRect)
 
 TEST_P (EntityTest, CanDrawRRect)
 
 TEST_P (EntityTest, GeometryBoundsAreTransformed)
 
 TEST_P (EntityTest, ThreeStrokesInOnePath)
 
 TEST_P (EntityTest, StrokeWithTextureContents)
 
 TEST_P (EntityTest, TriangleInsideASquare)
 
 TEST_P (EntityTest, StrokeCapAndJoinTest)
 
 TEST_P (EntityTest, CubicCurveTest)
 
 TEST_P (EntityTest, 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, 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, PointFieldCanUseCompute)
 
 TEST_P (EntityTest, ColorFilterContentsWithLargeGeometry)
 
 TEST_P (EntityTest, TextContentsCeilsGlyphScaleToDecimal)
 
 TEST_P (EntityTest, AdvancedBlendCoverageHintIsNotResetByEntityPass)
 
 TEST_P (EntityTest, SpecializationConstantsAreAppliedToVariants)
 
 TEST_P (EntityTest, DecalSpecializationAppliedToMorphologyFilter)
 
 TEST_P (EntityTest, FramebufferFetchPipelinesDeclareUsage)
 
 TEST_P (EntityTest, PipelineDescriptorEqAndHash)
 
 TEST_P (EntityTest, ContentContextOptionsHasReasonableHashFunctions)
 
 TEST (EntityGeometryTest, RectGeometryCoversArea)
 
 TEST (EntityGeometryTest, FillPathGeometryCoversArea)
 
 TEST (EntityGeometryTest, FillPathGeometryCoversAreaNoInnerRect)
 
 TEST (EntityGeometryTest, LineGeometryCoverage)
 
 TEST (EntityGeometryTest, RoundRectGeometryCoversArea)
 
 TEST (RenderTargetCacheTest, CachesUsedTexturesAcrossFrames)
 
 TEST (RenderTargetCacheTest, DoesNotPersistFailedAllocations)
 
 TEST (GeometryTest, ScalarNearlyEqual)
 
 TEST (GeometryTest, MakeColumn)
 
 TEST (GeometryTest, MakeRow)
 
 TEST (GeometryTest, RotationMatrix)
 
 TEST (GeometryTest, InvertMultMatrix)
 
 TEST (GeometryTest, MatrixBasis)
 
 TEST (GeometryTest, MutliplicationMatrix)
 
 TEST (GeometryTest, DeterminantTest)
 
 TEST (GeometryTest, InvertMatrix)
 
 TEST (GeometryTest, TestDecomposition)
 
 TEST (GeometryTest, TestDecomposition2)
 
 TEST (GeometryTest, TestRecomposition)
 
 TEST (GeometryTest, TestRecomposition2)
 
 TEST (GeometryTest, MatrixVectorMultiplication)
 
 TEST (GeometryTest, MatrixMakeRotationFromQuaternion)
 
 TEST (GeometryTest, MatrixTransformDirection)
 
 TEST (GeometryTest, MatrixGetMaxBasisLength)
 
 TEST (GeometryTest, MatrixGetMaxBasisLengthXY)
 
 TEST (GeometryTest, MatrixMakeOrthographic)
 
 TEST (GeometryTest, MatrixMakePerspective)
 
 TEST (GeometryTest, MatrixGetBasisVectors)
 
 TEST (GeometryTest, MatrixGetDirectionScale)
 
 TEST (GeometryTest, MatrixIsAligned)
 
 TEST (GeometryTest, MatrixTranslationScaleOnly)
 
 TEST (GeometryTest, MatrixLookAt)
 
 TEST (GeometryTest, QuaternionLerp)
 
 TEST (GeometryTest, QuaternionVectorMultiply)
 
 TEST (GeometryTest, CanGenerateMipCounts)
 
 TEST (GeometryTest, CanConvertTTypesExplicitly)
 
 TEST (GeometryTest, CanPerformAlgebraicPointOps)
 
 TEST (GeometryTest, CanPerformAlgebraicPointOpsWithArithmeticTypes)
 
 TEST (GeometryTest, PointIntegerCoercesToFloat)
 
 TEST (GeometryTest, SizeCoercesToPoint)
 
 TEST (GeometryTest, CanUsePointAssignmentOperators)
 
 TEST (GeometryTest, PointDotProduct)
 
 TEST (GeometryTest, PointCrossProduct)
 
 TEST (GeometryTest, PointReflect)
 
 TEST (GeometryTest, PointAbs)
 
 TEST (GeometryTest, PointAngleTo)
 
 TEST (GeometryTest, PointMin)
 
 TEST (GeometryTest, Vector3Min)
 
 TEST (GeometryTest, Vector4Min)
 
 TEST (GeometryTest, PointMax)
 
 TEST (GeometryTest, Vector3Max)
 
 TEST (GeometryTest, Vector4Max)
 
 TEST (GeometryTest, PointFloor)
 
 TEST (GeometryTest, Vector3Floor)
 
 TEST (GeometryTest, Vector4Floor)
 
 TEST (GeometryTest, PointCeil)
 
 TEST (GeometryTest, Vector3Ceil)
 
 TEST (GeometryTest, Vector4Ceil)
 
 TEST (GeometryTest, PointRound)
 
 TEST (GeometryTest, Vector3Round)
 
 TEST (GeometryTest, Vector4Round)
 
 TEST (GeometryTest, PointLerp)
 
 TEST (GeometryTest, Vector3Lerp)
 
 TEST (GeometryTest, Vector4Lerp)
 
 TEST (GeometryTest, CanUseVector3AssignmentOperators)
 
 TEST (GeometryTest, CanPerformAlgebraicVector3Ops)
 
 TEST (GeometryTest, CanPerformAlgebraicVector3OpsWithArithmeticTypes)
 
 TEST (GeometryTest, ColorPremultiply)
 
 TEST (GeometryTest, ColorR8G8B8A8)
 
 TEST (GeometryTest, ColorLerp)
 
 TEST (GeometryTest, ColorClamp01)
 
 TEST (GeometryTest, ColorMakeRGBA8)
 
 TEST (GeometryTest, ColorApplyColorMatrix)
 
 TEST (GeometryTest, ColorLinearToSRGB)
 
 TEST (GeometryTest, ColorSRGBToLinear)
 
 TEST (GeometryTest, BlendModeToString)
 
 TEST (GeometryTest, CanConvertBetweenDegressAndRadians)
 
 TEST (GeometryTest, RectUnion)
 
 TEST (GeometryTest, OptRectUnion)
 
 TEST (GeometryTest, RectIntersection)
 
 TEST (GeometryTest, OptRectIntersection)
 
 TEST (GeometryTest, RectIntersectsWithRect)
 
 TEST (GeometryTest, RectCutout)
 
 TEST (GeometryTest, RectContainsPoint)
 
 TEST (GeometryTest, RectContainsRect)
 
 TEST (GeometryTest, RectGetPoints)
 
 TEST (GeometryTest, RectShift)
 
 TEST (GeometryTest, RectGetTransformedPoints)
 
 TEST (GeometryTest, RectMakePointBounds)
 
 TEST (GeometryTest, RectExpand)
 
 TEST (GeometryTest, RectGetPositive)
 
 TEST (GeometryTest, RectScale)
 
 TEST (GeometryTest, RectDirections)
 
 TEST (GeometryTest, RectProject)
 
 TEST (GeometryTest, RectRoundOut)
 
 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 (RectTest, RectOriginSizeXYWHGetters)
 
 TEST (RectTest, IRectOriginSizeXYWHGetters)
 
 TEST (RectTest, RectFromRect)
 
 TEST (RectTest, RectFromIRect)
 
 TEST (RectTest, IRectFromRect)
 
 TEST (RectTest, IRectFromIRect)
 
 TEST (RectTest, RectMakeSize)
 
 TEST (RectTest, RectScale)
 
 TEST (RectTest, IRectScale)
 
 TEST (RectTest, RectArea)
 
 TEST (RectTest, IRectArea)
 
 TEST (RectTest, RectGetNormalizingTransform)
 
 TEST (RectTest, IRectGetNormalizingTransform)
 
 TEST (SizeTest, RectIsEmpty)
 
 TEST (SizeTest, IRectIsEmpty)
 
 TEST (RectTest, MakePointBoundsQuad)
 
 TEST (RectTest, IsSquare)
 
 TEST (RectTest, GetCenter)
 
 TEST (RectTest, RectExpand)
 
 TEST (RectTest, IRectExpand)
 
 TEST (RectTest, ContainsFloatingPoint)
 
 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 (BlitCommandVkTest, BlitCopyTextureToTextureCommandVK)
 
 TEST (BlitCommandVkTest, BlitCopyTextureToBufferCommandVK)
 
 TEST (BlitCommandVkTest, BlitCopyBufferToTextureCommandVK)
 
 TEST (BlitCommandVkTest, BlitGenerateMipmapCommandVK)
 
 TEST (CommandEncoderVKTest, DeleteEncoderAfterThreadDies)
 
 TEST (CommandEncoderVKTest, CleanupAfterSubmit)
 
 TEST (CommandPoolRecyclerVKTest, GetsACommandPoolPerThread)
 
 TEST (CommandPoolRecyclerVKTest, GetsTheSameCommandPoolOnSameThread)
 
 TEST (CommandPoolRecyclerVKTest, ReclaimMakesCommandPoolAvailable)
 
 TEST (ContextVKTest, DeletesCommandPools)
 
 TEST (ContextVKTest, DeletesCommandPoolsOnAllThreads)
 
 TEST (ContextVKTest, DeletePipelineAfterContext)
 
 TEST (ContextVKTest, DeleteShaderFunctionAfterContext)
 
 TEST (ContextVKTest, DeletePipelineLibraryAfterContext)
 
 TEST (ContextVKTest, CanCreateContextInAbsenceOfValidationLayers)
 
 TEST (ContextVKTest, CanCreateContextWithValidationLayers)
 
 TEST (DescriptorPoolRecyclerVKTest, GetDescriptorPoolRecyclerCreatesNewPools)
 
 TEST (DescriptorPoolRecyclerVKTest, DescriptorPoolCapacityIsRoundedUp)
 
 TEST (DescriptorPoolRecyclerVKTest, ReclaimMakesDescriptorPoolAvailable)
 
 TEST (DescriptorPoolRecyclerVKTest, ReclaimDropsDescriptorPoolIfSizeIsExceeded)
 
 TEST (FenceWaiterVKTest, IgnoresNullFence)
 
 TEST (FenceWaiterVKTest, IgnoresNullCallback)
 
 TEST (FenceWaiterVKTest, ExecutesFenceCallback)
 
 TEST (FenceWaiterVKTest, ExecutesFenceCallbackX2)
 
 TEST (FenceWaiterVKTest, ExecutesNewFenceThenOldFence)
 
 TEST (FenceWaiterVKTest, AddFenceDoesNothingIfTerminating)
 
 TEST (FenceWaiterVKTest, InProgressFencesStillWaitIfTerminated)
 
 TEST (PassBindingsCacheTest, bindPipeline)
 
 TEST (PassBindingsCacheTest, setStencilReference)
 
 TEST (PassBindingsCacheTest, setScissor)
 
 TEST (PassBindingsCacheTest, setViewport)
 
 TEST (ResourceManagerVKTest, CreatesANewInstance)
 
 TEST (ResourceManagerVKTest, ReclaimMovesAResourceAndDestroysIt)
 
 TEST (ResourceManagerVKTest, TerminatesWhenOutOfScope)
 
 TEST (ResourceManagerVKTest, IsThreadSafe)
 
 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)
 
 INSTANTIATE_COMPUTE_SUITE (ComputeSubgroupTest)
 
 TEST_P (ComputeSubgroupTest, CapabilitiesSuportSubgroups)
 
 TEST_P (ComputeSubgroupTest, PathPlayground)
 
 TEST_P (ComputeSubgroupTest, LargePath)
 
 TEST_P (ComputeSubgroupTest, QuadAndCubicInOnePath)
 
 TEST_P (ComputeTest, CapabilitiesReportSupport)
 
 TEST_P (ComputeTest, CanCreateComputePass)
 
 TEST_P (ComputeTest, CanComputePrefixSum)
 
 TEST_P (ComputeTest, 1DThreadgroupSizingIsCorrect)
 
 TEST_P (ComputeTest, CanComputePrefixSumLargeInteractive)
 
 TEST_P (ComputeTest, MultiStageInputAndOutput)
 
 TEST_P (ComputeTest, CanCompute1DimensionalData)
 
 TEST_P (ComputeTest, ReturnsEarlyWhenAnyGridDimensionIsZero)
 
 TEST (HostBufferTest, TestInitialization)
 
 TEST (HostBufferTest, CanEmplace)
 
 TEST (HostBufferTest, CanEmplaceWithAlignment)
 
 TEST (PipelineDescriptorTest, PrimitiveTypeHashEquality)
 
 TEST (PoolTest, Simple)
 
 TEST (PoolTest, Overload)
 
static void InstantiateTestShaderLibrary ()
 
 INSTANTIATE_PLAYGROUND_SUITE (RendererDartTest)
 
 TEST_P (RendererDartTest, CanRunDartInPlaygroundFrame)
 
 TEST_P (RendererDartTest, CanInstantiateFlutterGPUContext)
 
 DART_TEST_CASE (canEmplaceHostBuffer)
 
 DART_TEST_CASE (canCreateDeviceBuffer)
 
 DART_TEST_CASE (canOverwriteDeviceBuffer)
 
 DART_TEST_CASE (deviceBufferOverwriteFailsWhenOutOfBounds)
 
 DART_TEST_CASE (deviceBufferOverwriteThrowsForNegativeDestinationOffset)
 
 DART_TEST_CASE (canCreateTexture)
 
 DART_TEST_CASE (canOverwriteTexture)
 
 DART_TEST_CASE (textureOverwriteThrowsForWrongBufferSize)
 
 DART_TEST_CASE (textureAsImageReturnsAValidUIImageHandle)
 
 DART_TEST_CASE (textureAsImageThrowsWhenNotShaderReadable)
 
 DART_TEST_CASE (canCreateShaderLibrary)
 
 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, CanPreAllocateCommands)
 
 TEST_P (RendererTest, CanLookupRenderTargetProperties)
 
 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)
 
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, GlyphAtlasTextureIsRecycledWhenContentsAreRecreated)
 

Variables

static constexpr std::string_view kFontFixture
 
static int64_t LastSample = 0
 
std::vector< Pointgolden_cubic_and_quad_points
 

Typedef Documentation

◆ AiksCanvasTest

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

Definition at line 16 of file canvas_unittests.cc.

◆ AiksTest

Definition at line 17 of file aiks_unittests.h.

◆ ArchiveTest

Definition at line 110 of file archivist_unittests.cc.

◆ BlitPassTest

Definition at line 15 of file blit_pass_unittests.cc.

◆ ComputeSubgroupTest

◆ ComputeTest

Definition at line 26 of file compute_unittests.cc.

◆ DeviceBufferTest

Definition at line 12 of file device_buffer_unittests.cc.

◆ DisplayListTest

Definition at line 46 of file dl_unittests.cc.

◆ EntityPassTargetTest

◆ EntityTest

◆ RendererTest

Definition at line 43 of file renderer_unittests.cc.

◆ RuntimeStageTest

◆ TypographerTest

Function Documentation

◆ APPLY_COLOR_FILTER_GRADIENT_TEST() [1/4]

impeller::testing::APPLY_COLOR_FILTER_GRADIENT_TEST ( Conical  )

◆ APPLY_COLOR_FILTER_GRADIENT_TEST() [2/4]

impeller::testing::APPLY_COLOR_FILTER_GRADIENT_TEST ( Linear  )

◆ APPLY_COLOR_FILTER_GRADIENT_TEST() [3/4]

impeller::testing::APPLY_COLOR_FILTER_GRADIENT_TEST ( Radial  )

◆ APPLY_COLOR_FILTER_GRADIENT_TEST() [4/4]

impeller::testing::APPLY_COLOR_FILTER_GRADIENT_TEST ( Sweep  )

◆ BlendModeTest()

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

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

Definition at line 2196 of file aiks_unittests.cc.

2198  {
2199  Color destination_color = Color::CornflowerBlue().WithAlpha(0.75);
2200  auto source_colors = std::vector<Color>({Color::White().WithAlpha(0.75),
2201  Color::LimeGreen().WithAlpha(0.75),
2202  Color::Black().WithAlpha(0.75)});
2203 
2204  Canvas canvas;
2205 
2206  canvas.DrawPaint({.color = Color::Black()});
2207 
2208  //----------------------------------------------------------------------------
2209  /// 1. Save layer blending (top squares).
2210  ///
2211 
2212  canvas.Save();
2213  for (const auto& color : source_colors) {
2214  canvas.Save();
2215  {
2216  canvas.ClipRect(Rect::MakeXYWH(50, 50, 100, 100));
2217  // Perform the blend in a SaveLayer so that the initial backdrop color is
2218  // fully transparent black. SourceOver blend the result onto the parent
2219  // pass.
2220  canvas.SaveLayer({});
2221  {
2222  canvas.DrawPaint({.color = destination_color});
2223  // Draw the source color in an offscreen pass and blend it to the parent
2224  // pass.
2225  canvas.SaveLayer({.blend_mode = blend_mode});
2226  { //
2227  canvas.DrawRect(Rect::MakeXYWH(50, 50, 100, 100), {.color = color});
2228  }
2229  canvas.Restore();
2230  }
2231  canvas.Restore();
2232  }
2233  canvas.Restore();
2234  canvas.Translate(Vector2(100, 0));
2235  }
2236  canvas.RestoreToCount(0);
2237 
2238  //----------------------------------------------------------------------------
2239  /// 2. CPU blend modes (bottom squares).
2240  ///
2241 
2242  canvas.Save();
2243  canvas.Translate({0, 100});
2244 
2245  // Perform the blend in a SaveLayer so that the initial backdrop color is
2246  // fully transparent black. SourceOver blend the result onto the parent pass.
2247  canvas.SaveLayer({});
2248  // canvas.DrawPaint({.color = destination_color});
2249  for (const auto& color : source_colors) {
2250  // Simply write the CPU blended color to the pass.
2251  canvas.DrawRect(Rect::MakeXYWH(50, 50, 100, 100),
2252  {.color = destination_color.Blend(color, blend_mode),
2253  .blend_mode = BlendMode::kSourceOver});
2254  canvas.Translate(Vector2(100, 0));
2255  }
2256  canvas.RestoreToCount(0);
2257 
2258  //----------------------------------------------------------------------------
2259  /// 3. Image blending (top right).
2260  ///
2261  /// Compare these results with the images in the Flutter blend mode
2262  /// documentation: https://api.flutter.dev/flutter/dart-ui/BlendMode.html
2263  ///
2264 
2265  canvas.Save();
2266  // canvas.ClipRect(Rect::MakeXYWH(500, 0, 500, 500));
2267  canvas.SaveLayer({.blend_mode = BlendMode::kSourceOver});
2268  {
2269  canvas.DrawImage(dst_image, {400, 50}, {.blend_mode = BlendMode::kSource});
2270  canvas.DrawImage(src_image, {400, 50}, {.blend_mode = blend_mode});
2271  }
2272  canvas.RestoreToCount(0);
2273 
2274  return canvas.EndRecordingAsPicture();
2275 }

References impeller::Color::Black(), impeller::Color::Blend(), impeller::Color::CornflowerBlue(), impeller::Canvas::DrawPaint(), impeller::kSource, impeller::kSourceOver, impeller::Color::LimeGreen(), 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 169 of file aiks_gradient_unittests.cc.

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

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 85 of file aiks_gradient_unittests.cc.

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

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 113 of file aiks_gradient_unittests.cc.

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

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 140 of file aiks_gradient_unittests.cc.

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

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 1109 of file renderer_unittests.cc.

1109  {
1110  static CompareFunctionUIData data;
1111  return data;
1112 }

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 25 of file vertices_contents_unittests.cc.

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

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

Referenced by TEST_P().

◆ CreateGlyphAtlas()

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

Definition at line 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(), and impeller::TypographerContext::CreateGlyphAtlas().

Referenced by TEST_P().

◆ CreateMappingFromString()

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

Definition at line 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,
bool  collapse = false 
)

Definition at line 105 of file entity_unittests.cc.

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

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

2052  {
2053  Vector3 red = {244.0 / 255.0, 67.0 / 255.0, 54.0 / 255.0};
2054  Vector3 green = {76.0 / 255.0, 175.0 / 255.0, 80.0 / 255.0};
2055  Vector3 blue = {33.0 / 255.0, 150.0 / 255.0, 243.0 / 255.0};
2056  Vector3 white = {1.0, 1.0, 1.0};
2057  Vector3 red_yuv = RGBToYUV(red, yuv_color_space);
2058  Vector3 green_yuv = RGBToYUV(green, yuv_color_space);
2059  Vector3 blue_yuv = RGBToYUV(blue, yuv_color_space);
2060  Vector3 white_yuv = RGBToYUV(white, yuv_color_space);
2061  std::vector<Vector3> yuvs{red_yuv, green_yuv, blue_yuv, white_yuv};
2062  std::vector<uint8_t> y_data;
2063  std::vector<uint8_t> uv_data;
2064  for (int i = 0; i < 4; i++) {
2065  auto yuv = yuvs[i];
2066  uint8_t y = std::round(yuv.x * 255.0);
2067  uint8_t u = std::round(yuv.y * 255.0);
2068  uint8_t v = std::round(yuv.z * 255.0);
2069  for (int j = 0; j < 16; j++) {
2070  y_data.push_back(y);
2071  }
2072  for (int j = 0; j < 8; j++) {
2073  uv_data.push_back(j % 2 == 0 ? u : v);
2074  }
2075  }
2076  impeller::TextureDescriptor y_texture_descriptor;
2077  y_texture_descriptor.storage_mode = impeller::StorageMode::kHostVisible;
2078  y_texture_descriptor.format = PixelFormat::kR8UNormInt;
2079  y_texture_descriptor.size = {8, 8};
2080  auto y_texture =
2081  context->GetResourceAllocator()->CreateTexture(y_texture_descriptor);
2082  auto y_mapping = std::make_shared<fml::DataMapping>(y_data);
2083  if (!y_texture->SetContents(y_mapping)) {
2084  FML_DLOG(ERROR) << "Could not copy contents into Y texture.";
2085  }
2086 
2087  impeller::TextureDescriptor uv_texture_descriptor;
2088  uv_texture_descriptor.storage_mode = impeller::StorageMode::kHostVisible;
2089  uv_texture_descriptor.format = PixelFormat::kR8G8UNormInt;
2090  uv_texture_descriptor.size = {4, 4};
2091  auto uv_texture =
2092  context->GetResourceAllocator()->CreateTexture(uv_texture_descriptor);
2093  auto uv_mapping = std::make_shared<fml::DataMapping>(uv_data);
2094  if (!uv_texture->SetContents(uv_mapping)) {
2095  FML_DLOG(ERROR) << "Could not copy contents into UV texture.";
2096  }
2097 
2098  return {y_texture, uv_texture};
2099 }

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

impeller::testing::DART_TEST_CASE ( canCreateDeviceBuffer  )

◆ DART_TEST_CASE() [2/12]

impeller::testing::DART_TEST_CASE ( canCreateRenderPassAndSubmit  )

◆ DART_TEST_CASE() [3/12]

impeller::testing::DART_TEST_CASE ( canCreateShaderLibrary  )

◆ DART_TEST_CASE() [4/12]

impeller::testing::DART_TEST_CASE ( canCreateTexture  )

◆ DART_TEST_CASE() [5/12]

impeller::testing::DART_TEST_CASE ( canEmplaceHostBuffer  )

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

◆ DART_TEST_CASE() [6/12]

impeller::testing::DART_TEST_CASE ( canOverwriteDeviceBuffer  )

◆ DART_TEST_CASE() [7/12]

impeller::testing::DART_TEST_CASE ( canOverwriteTexture  )

◆ DART_TEST_CASE() [8/12]

impeller::testing::DART_TEST_CASE ( deviceBufferOverwriteFailsWhenOutOfBounds  )

◆ DART_TEST_CASE() [9/12]

impeller::testing::DART_TEST_CASE ( deviceBufferOverwriteThrowsForNegativeDestinationOffset  )

◆ DART_TEST_CASE() [10/12]

impeller::testing::DART_TEST_CASE ( textureAsImageReturnsAValidUIImageHandle  )

◆ DART_TEST_CASE() [11/12]

impeller::testing::DART_TEST_CASE ( textureAsImageThrowsWhenNotShaderReadable  )

◆ DART_TEST_CASE() [12/12]

impeller::testing::DART_TEST_CASE ( textureOverwriteThrowsForWrongBufferSize  )

◆ GetBlendModeSelection()

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

Definition at line 1007 of file aiks_unittests.cc.

1007  {
1008  std::vector<const char*> blend_mode_names;
1009  std::vector<BlendMode> blend_mode_values;
1010  {
1011  const std::vector<std::tuple<const char*, BlendMode>> blends = {
1013  assert(blends.size() ==
1014  static_cast<size_t>(Entity::kLastAdvancedBlendMode) + 1);
1015  for (const auto& [name, mode] : blends) {
1016  blend_mode_names.push_back(name);
1017  blend_mode_values.push_back(mode);
1018  }
1019  }
1020 
1021  return {blend_mode_names, blend_mode_values};
1022 }

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 1748 of file dl_unittests.cc.

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

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

◆ INSTANTIATE_COMPUTE_SUITE()

impeller::testing::INSTANTIATE_COMPUTE_SUITE ( ComputeSubgroupTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [1/8]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( AiksTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [2/8]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( BlitPassTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [3/8]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( DirectionalGaussianBlurFilterContentsTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [4/8]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( DisplayListTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [5/8]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( EntityPassTargetTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [6/8]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( GaussianBlurFilterContentsTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [7/8]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( RendererDartTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [8/8]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( RuntimeStageTest  )

◆ InstantiateTestShaderLibrary()

static void impeller::testing::InstantiateTestShaderLibrary ( )
static

Definition at line 32 of file renderer_dart_unittests.cc.

32  {
33  auto fixture =
34  flutter::testing::OpenFixtureAsMapping("playground.shaderbundle");
35  auto library =
36  flutter::gpu::ShaderLibrary::MakeFromFlatbuffer(std::move(fixture));
37  flutter::gpu::ShaderLibrary::SetOverride(library);
38 }

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

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

688  {}) {
689  // Draw the baseline.
690  canvas.DrawRect(
691  Rect::MakeXYWH(options.position.x - 50, options.position.y, 900, 10),
692  Paint{.color = Color::Aqua().WithAlpha(0.25)});
693 
694  // Mark the point at which the text is drawn.
695  canvas.DrawCircle(options.position, 5.0,
696  Paint{.color = Color::Red().WithAlpha(0.25)});
697 
698  // Construct the text blob.
699  auto c_font_fixture = std::string(font_fixture);
700  auto mapping = flutter::testing::OpenFixtureAsSkData(c_font_fixture.c_str());
701  if (!mapping) {
702  return false;
703  }
704  sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
705  SkFont sk_font(font_mgr->makeFromData(mapping), options.font_size);
706  auto blob = SkTextBlob::MakeFromString(text.c_str(), sk_font);
707  if (!blob) {
708  return false;
709  }
710 
711  // Create the Impeller text frame and draw it at the designated baseline.
712  auto frame = MakeTextFrameFromTextBlobSkia(blob);
713 
714  Paint text_paint;
715  text_paint.color = options.color;
716  text_paint.mask_blur_descriptor = options.mask_blur_descriptor;
717  canvas.DrawTextFrame(frame, options.position, text_paint);
718  return true;
719 }

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

725  {}) {
726  // Draw the baseline.
727  canvas.DrawRect(
728  Rect::MakeXYWH(options.position.x - 50, options.position.y, 900, 10),
729  Paint{.color = Color::Aqua().WithAlpha(0.25)});
730 
731  // Mark the point at which the text is drawn.
732  canvas.DrawCircle(options.position, 5.0,
733  Paint{.color = Color::Red().WithAlpha(0.25)});
734 
735  // Construct the text blob.
736  auto mapping = flutter::testing::OpenFixtureAsMapping(font_fixture.c_str());
737  if (!mapping) {
738  return false;
739  }
740  auto typeface_stb = std::make_shared<TypefaceSTB>(std::move(mapping));
741 
742  auto frame = MakeTextFrameSTB(
743  typeface_stb, Font::Metrics{.point_size = options.font_size}, text);
744 
745  Paint text_paint;
746  text_paint.color = options.color;
747  canvas.DrawTextFrame(frame, options.position, text_paint);
748  return true;
749 }

Referenced by TEST_P().

◆ RGBToYUV()

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

Definition at line 2033 of file entity_unittests.cc.

2033  {
2034  Vector3 yuv;
2035  switch (yuv_color_space) {
2036  case YUVColorSpace::kBT601FullRange:
2037  yuv.x = rgb.x * 0.299 + rgb.y * 0.587 + rgb.z * 0.114;
2038  yuv.y = rgb.x * -0.169 + rgb.y * -0.331 + rgb.z * 0.5 + 0.5;
2039  yuv.z = rgb.x * 0.5 + rgb.y * -0.419 + rgb.z * -0.081 + 0.5;
2040  break;
2041  case YUVColorSpace::kBT601LimitedRange:
2042  yuv.x = rgb.x * 0.257 + rgb.y * 0.516 + rgb.z * 0.100 + 0.063;
2043  yuv.y = rgb.x * -0.145 + rgb.y * -0.291 + rgb.z * 0.439 + 0.5;
2044  yuv.z = rgb.x * 0.429 + rgb.y * -0.368 + rgb.z * -0.071 + 0.5;
2045  break;
2046  }
2047  return yuv;
2048 }

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

Referenced by CreateTestYUVTextures().

◆ TEST() [1/299]

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

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

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

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(std::move(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/299]

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(std::move(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/299]

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(std::move(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/299]

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(std::move(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/299]

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(std::move(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/299]

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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 = context->GetResourceAllocator()
58  ->CreateBuffer({
59  .size = 1,
60  })
61  ->AsBufferView();
62  bool result = cmd.Encode(*encoder.get());
63  EXPECT_TRUE(result);
64  EXPECT_TRUE(encoder->IsTracking(cmd.source.buffer));
65  EXPECT_TRUE(encoder->IsTracking(cmd.destination));
66 }

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

◆ TEST() [31/299]

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

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

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

Definition at line 68 of file blit_command_vk_unittests.cc.

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

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

◆ TEST() [34/299]

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

Definition at line 192 of file canvas_recorder_unittests.cc.

192  {
193  CanvasRecorder<Serializer> recorder;
194  recorder.ClipPath({});
195  ASSERT_EQ(recorder.GetSerializer().last_op_, CanvasRecorderOp::kClipPath);
196 }

References impeller::kClipPath.

◆ TEST() [35/299]

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

Definition at line 198 of file canvas_recorder_unittests.cc.

198  {
199  CanvasRecorder<Serializer> recorder;
200  recorder.ClipRect({});
201  ASSERT_EQ(recorder.GetSerializer().last_op_, CanvasRecorderOp::kClipRect);
202 }

References impeller::kClipRect.

◆ TEST() [36/299]

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

Definition at line 204 of file canvas_recorder_unittests.cc.

204  {
205  CanvasRecorder<Serializer> recorder;
206  recorder.ClipRRect({}, {});
207  ASSERT_EQ(recorder.GetSerializer().last_op_, CanvasRecorderOp::kClipRRect);
208 }

References impeller::kClipRRect.

◆ TEST() [37/299]

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

Definition at line 101 of file canvas_recorder_unittests.cc.

101  {
102  CanvasRecorder<Serializer> recorder;
103  recorder.Concat(Matrix());
104  ASSERT_EQ(recorder.GetSerializer().last_op_, CanvasRecorderOp::kConcat);
105 }

References impeller::kConcat.

◆ TEST() [38/299]

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

Definition at line 231 of file canvas_recorder_unittests.cc.

231  {
232  CanvasRecorder<Serializer> recorder;
233  recorder.DrawAtlas({}, {}, {}, {}, {}, {}, {}, {});
234  ASSERT_EQ(recorder.GetSerializer().last_op_, CanvasRecorderOp::kDrawAtlas);
235 }

References impeller::kDrawAtlas.

◆ TEST() [39/299]

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

Definition at line 167 of file canvas_recorder_unittests.cc.

167  {
168  CanvasRecorder<Serializer> recorder;
169  recorder.DrawCircle(Point(), 0, Paint());
170  ASSERT_EQ(recorder.GetSerializer().last_op_, CanvasRecorderOp::kDrawCircle);
171 }

References impeller::kDrawCircle.

◆ TEST() [40/299]

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

Definition at line 179 of file canvas_recorder_unittests.cc.

179  {
180  CanvasRecorder<Serializer> recorder;
181  recorder.DrawImage({}, {}, {}, {});
182  ASSERT_EQ(recorder.GetSerializer().last_op_, CanvasRecorderOp::kDrawImage);
183 }

References impeller::kDrawImage.

◆ TEST() [41/299]

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

Definition at line 185 of file canvas_recorder_unittests.cc.

185  {
186  CanvasRecorder<Serializer> recorder;
187  recorder.DrawImageRect({}, {}, {}, {}, {});
188  ASSERT_EQ(recorder.GetSerializer().last_op_,
190 }

References impeller::kDrawImageRect.

◆ TEST() [42/299]

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

Definition at line 149 of file canvas_recorder_unittests.cc.

149  {
150  CanvasRecorder<Serializer> recorder;
151  recorder.DrawPaint(Paint());
152  ASSERT_EQ(recorder.GetSerializer().last_op_, CanvasRecorderOp::kDrawPaint);
153 }

References impeller::kDrawPaint.

◆ TEST() [43/299]

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

Definition at line 143 of file canvas_recorder_unittests.cc.

143  {
144  CanvasRecorder<Serializer> recorder;
145  recorder.DrawPath(Path(), Paint());
146  ASSERT_EQ(recorder.GetSerializer().last_op_, CanvasRecorderOp::kDrawPath);
147 }

References impeller::kDrawPath.

◆ TEST() [44/299]

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

Definition at line 210 of file canvas_recorder_unittests.cc.

210  {
211  CanvasRecorder<Serializer> recorder;
212  recorder.DrawPicture({});
213  ASSERT_EQ(recorder.GetSerializer().last_op_, CanvasRecorderOp::kDrawPicture);
214 }

References impeller::kDrawPicture.

◆ TEST() [45/299]

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

Definition at line 173 of file canvas_recorder_unittests.cc.

173  {
174  CanvasRecorder<Serializer> recorder;
175  recorder.DrawPoints(std::vector<Point>{}, 0, Paint(), PointStyle::kRound);
176  ASSERT_EQ(recorder.GetSerializer().last_op_, CanvasRecorderOp::kDrawPoints);
177 }

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

◆ TEST() [46/299]

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

Definition at line 155 of file canvas_recorder_unittests.cc.

155  {
156  CanvasRecorder<Serializer> recorder;
157  recorder.DrawRect(Rect(), Paint());
158  ASSERT_EQ(recorder.GetSerializer().last_op_, CanvasRecorderOp::kDrawRect);
159 }

References impeller::kDrawRect.

◆ TEST() [47/299]

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

Definition at line 161 of file canvas_recorder_unittests.cc.

161  {
162  CanvasRecorder<Serializer> recorder;
163  recorder.DrawRRect(Rect(), {}, Paint());
164  ASSERT_EQ(recorder.GetSerializer().last_op_, CanvasRecorderOp::kDrawRRect);
165 }

References impeller::kDrawRRect.

◆ TEST() [48/299]

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

Definition at line 216 of file canvas_recorder_unittests.cc.

216  {
217  CanvasRecorder<Serializer> recorder;
218  recorder.DrawTextFrame({}, {}, {});
219  ASSERT_EQ(recorder.GetSerializer().last_op_,
221 }

References impeller::kDrawTextFrame.

◆ TEST() [49/299]

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

Definition at line 223 of file canvas_recorder_unittests.cc.

223  {
224  CanvasRecorder<Serializer> recorder;
225  auto geometry = std::shared_ptr<VerticesGeometry>(
226  new VerticesGeometry({}, {}, {}, {}, {}, {}));
227  recorder.DrawVertices(geometry, {}, {});
228  ASSERT_EQ(recorder.GetSerializer().last_op_, CanvasRecorderOp::kDrawVertices);
229 }

References impeller::kDrawVertices.

◆ TEST() [50/299]

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

Definition at line 107 of file canvas_recorder_unittests.cc.

107  {
108  CanvasRecorder<Serializer> recorder;
109  recorder.PreConcat(Matrix());
110  ASSERT_EQ(recorder.GetSerializer().last_op_, CanvasRecorderOp::kPreConcat);
111 }

References impeller::kPreConcat.

◆ TEST() [51/299]

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

Definition at line 88 of file canvas_recorder_unittests.cc.

88  {
89  CanvasRecorder<Serializer> recorder;
90  recorder.ResetTransform();
91  ASSERT_EQ(recorder.GetSerializer().last_op_,
93 }

References impeller::kResetTransform.

◆ TEST() [52/299]

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

Definition at line 74 of file canvas_recorder_unittests.cc.

74  {
75  CanvasRecorder<Serializer> recorder;
76  recorder.Restore();
77  ASSERT_EQ(recorder.GetSerializer().last_op_, CanvasRecorderOp::kRestore);
78 }

References impeller::kRestore.

◆ TEST() [53/299]

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

Definition at line 80 of file canvas_recorder_unittests.cc.

80  {
81  CanvasRecorder<Serializer> recorder;
82  recorder.Save();
83  recorder.RestoreToCount(0);
84  ASSERT_EQ(recorder.GetSerializer().last_op_,
86 }

References impeller::kRestoreToCount.

◆ TEST() [54/299]

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

Definition at line 137 of file canvas_recorder_unittests.cc.

137  {
138  CanvasRecorder<Serializer> recorder;
139  recorder.Rotate(Radians(0));
140  ASSERT_EQ(recorder.GetSerializer().last_op_, CanvasRecorderOp::kRotate);
141 }

References impeller::kRotate.

◆ TEST() [55/299]

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

Definition at line 61 of file canvas_recorder_unittests.cc.

61  {
62  CanvasRecorder<Serializer> recorder;
63  recorder.Save();
64  ASSERT_EQ(recorder.GetSerializer().last_op_, CanvasRecorderOp::kSave);
65 }

References impeller::kSave.

◆ TEST() [56/299]

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

Definition at line 67 of file canvas_recorder_unittests.cc.

67  {
68  CanvasRecorder<Serializer> recorder;
69  Paint paint;
70  recorder.SaveLayer(paint);
71  ASSERT_EQ(recorder.GetSerializer().last_op_, CanvasRecorderOp::kSaveLayer);
72 }

References impeller::kSaveLayer.

◆ TEST() [57/299]

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

Definition at line 119 of file canvas_recorder_unittests.cc.

119  {
120  CanvasRecorder<Serializer> recorder;
121  recorder.Scale(Vector2());
122  ASSERT_EQ(recorder.GetSerializer().last_op_, CanvasRecorderOp::kScale2);
123 }

References impeller::kScale2.

◆ TEST() [58/299]

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

Definition at line 125 of file canvas_recorder_unittests.cc.

125  {
126  CanvasRecorder<Serializer> recorder;
127  recorder.Scale(Vector3());
128  ASSERT_EQ(recorder.GetSerializer().last_op_, CanvasRecorderOp::kScale3);
129 }

References impeller::kScale3.

◆ TEST() [59/299]

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

Definition at line 131 of file canvas_recorder_unittests.cc.

131  {
132  CanvasRecorder<Serializer> recorder;
133  recorder.Skew(0, 0);
134  ASSERT_EQ(recorder.GetSerializer().last_op_, CanvasRecorderOp::kSkew);
135 }

References impeller::kSkew.

◆ TEST() [60/299]

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

Definition at line 95 of file canvas_recorder_unittests.cc.

95  {
96  CanvasRecorder<Serializer> recorder;
97  recorder.Transform(Matrix());
98  ASSERT_EQ(recorder.GetSerializer().last_op_, CanvasRecorderOp::kTransform);
99 }

References impeller::kTransform.

◆ TEST() [61/299]

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

Definition at line 113 of file canvas_recorder_unittests.cc.

113  {
114  CanvasRecorder<Serializer> recorder;
115  recorder.Translate(Vector3());
116  ASSERT_EQ(recorder.GetSerializer().last_op_, CanvasRecorderOp::kTranslate);
117 }

References impeller::kTranslate.

◆ TEST() [62/299]

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

Definition at line 32 of file capabilities_unittests.cc.

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

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

◆ TEST() [63/299]

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

Definition at line 50 of file capabilities_unittests.cc.

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

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

◆ TEST() [64/299]

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

Definition at line 41 of file capabilities_unittests.cc.

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

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

◆ TEST() [65/299]

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

Definition at line 41 of file command_encoder_vk_unittests.cc.

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

References impeller::CommandEncoderFactoryVK::Create().

◆ TEST() [66/299]

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

Definition at line 15 of file command_encoder_vk_unittests.cc.

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

References impeller::CommandEncoderFactoryVK::Create().

◆ TEST() [67/299]

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

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

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

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

Definition at line 191 of file base_unittests.cc.

191  {
192  std::vector<std::thread> threads;
193  const auto kThreadCount = 10u;
194 
195  Mutex mtx;
196  ConditionVariable cv;
197  size_t sum = 0u;
198 
199  std::condition_variable start_cv;
200  std::mutex start_mtx;
201  bool start = false;
202  auto start_predicate = [&start]() { return start; };
203  auto thread_main = [&]() {
204  {
205  std::unique_lock start_lock(start_mtx);
206  start_cv.wait(start_lock, start_predicate);
207  }
208 
209  mtx.Lock();
210  cv.Wait(mtx, []() { return true; });
211  auto old_val = sum;
212  std::this_thread::sleep_for(std::chrono::milliseconds{100u});
213  sum = old_val + 1u;
214  mtx.Unlock();
215  };
216  // Launch all threads. They will wait for the start CV to be signaled.
217  for (size_t i = 0; i < kThreadCount; i++) {
218  threads.emplace_back(thread_main);
219  }
220  // Notify all threads that the test may start.
221  {
222  {
223  std::scoped_lock start_lock(start_mtx);
224  start = true;
225  }
226  start_cv.notify_all();
227  }
228  // Join all threads.
229  ASSERT_EQ(threads.size(), kThreadCount);
230  for (size_t i = 0; i < kThreadCount; i++) {
231  threads[i].join();
232  }
233  ASSERT_EQ(sum, kThreadCount);
234 }

References impeller::ConditionVariable::Wait().

◆ TEST() [71/299]

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

Definition at line 146 of file base_unittests.cc.

146  {
147  std::vector<std::thread> threads;
148  const auto kThreadCount = 10u;
149 
150  Mutex mtx;
151  ConditionVariable cv;
152  size_t sum = 0u;
153 
154  std::condition_variable start_cv;
155  std::mutex start_mtx;
156  bool start = false;
157  auto start_predicate = [&start]() { return start; };
158  auto thread_main = [&]() {
159  {
160  std::unique_lock start_lock(start_mtx);
161  start_cv.wait(start_lock, start_predicate);
162  }
163 
164  mtx.Lock();
165  cv.WaitFor(mtx, std::chrono::milliseconds{0u}, []() { return true; });
166  auto old_val = sum;
167  std::this_thread::sleep_for(std::chrono::milliseconds{100u});
168  sum = old_val + 1u;
169  mtx.Unlock();
170  };
171  // Launch all threads. They will wait for the start CV to be signaled.
172  for (size_t i = 0; i < kThreadCount; i++) {
173  threads.emplace_back(thread_main);
174  }
175  // Notify all threads that the test may start.
176  {
177  {
178  std::scoped_lock start_lock(start_mtx);
179  start = true;
180  }
181  start_cv.notify_all();
182  }
183  // Join all threads.
184  ASSERT_EQ(threads.size(), kThreadCount);
185  for (size_t i = 0; i < kThreadCount; i++) {
186  threads[i].join();
187  }
188  ASSERT_EQ(sum, kThreadCount);
189 }

References impeller::ConditionVariable::WaitFor().

◆ TEST() [72/299]

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

Definition at line 108 of file base_unittests.cc.

108  {
109  CVTest test;
110  // test.rando_ivar = 12; // <--- Static analysis error
111  for (size_t i = 0; i < 2; ++i) {
112  test.mutex.Lock(); // <--- Static analysis error without this.
113  auto result = test.cv.WaitFor(
114  test.mutex, std::chrono::milliseconds{10},
115  [&]() IPLR_REQUIRES(test.mutex) {
116  test.rando_ivar = 12; // <-- Static analysics error without the
117  // IPLR_REQUIRES on the pred.
118  return false;
119  });
120  test.mutex.Unlock();
121  ASSERT_FALSE(result);
122  }
123  Lock lock(test.mutex); // <--- Static analysis error without this.
124  // The predicate never returns true. So return has to be due to a non-spurious
125  // wake.
126  ASSERT_EQ(test.rando_ivar, 12u);
127 }

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

◆ TEST() [73/299]

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

Definition at line 129 of file base_unittests.cc.

129  {
130  CVTest test;
131  // test.rando_ivar = 12; // <--- Static analysis error
132  for (size_t i = 0; i < 2; ++i) {
133  test.mutex.Lock(); // <--- Static analysis error without this.
134  test.cv.Wait(test.mutex, [&]() IPLR_REQUIRES(test.mutex) {
135  test.rando_ivar = 12; // <-- Static analysics error without
136  // the IPLR_REQUIRES on the pred.
137  return true;
138  });
139  test.mutex.Unlock();
140  }
141  Lock lock(test.mutex); // <--- Static analysis error without this.
142  // The wake only happens when the predicate returns true.
143  ASSERT_EQ(test.rando_ivar, 12u);
144 }

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

◆ TEST() [74/299]

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

Definition at line 85 of file base_unittests.cc.

85  {
86  CVTest test;
87  // test.rando_ivar = 12; // <--- Static analysis error
88  for (size_t i = 0; i < 2; ++i) {
89  test.mutex.Lock(); // <--- Static analysis error without this.
90  auto result = test.cv.WaitUntil(
91  test.mutex,
92  std::chrono::high_resolution_clock::now() +
93  std::chrono::milliseconds{10},
94  [&]() IPLR_REQUIRES(test.mutex) {
95  test.rando_ivar = 12; // <-- Static analysics error without the
96  // IPLR_REQUIRES on the pred.
97  return false;
98  });
99  test.mutex.Unlock();
100  ASSERT_FALSE(result);
101  }
102  Lock lock(test.mutex); // <--- Static analysis error without this.
103  // The predicate never returns true. So return has to be due to a non-spurious
104  // wake.
105  ASSERT_EQ(test.rando_ivar, 12u);
106 }

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

◆ TEST() [75/299]

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

Definition at line 117 of file context_vk_unittests.cc.

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

References impeller::CapabilitiesVK::AreValidationsEnabled().

◆ TEST() [76/299]

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

Definition at line 131 of file context_vk_unittests.cc.

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

References impeller::CapabilitiesVK::AreValidationsEnabled().

◆ TEST() [77/299]

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

Definition at line 60 of file context_vk_unittests.cc.

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

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

◆ TEST() [78/299]

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

Definition at line 101 of file context_vk_unittests.cc.

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

References impeller::PipelineDescriptor::SetVertexDescriptor().

◆ TEST() [79/299]

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

Definition at line 14 of file context_vk_unittests.cc.

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

◆ TEST() [80/299]

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

Definition at line 29 of file context_vk_unittests.cc.

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

◆ TEST() [81/299]

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

Definition at line 79 of file context_vk_unittests.cc.

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

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

◆ TEST() [82/299]

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

Definition at line 26 of file descriptor_pool_vk_unittests.cc.

26  {
27  auto const context = MockVulkanContextBuilder().Build();
28  auto const [pool1, capacity] = context->GetDescriptorPoolRecycler()->Get(1);
29 
30  // Rounds up to a minimum of 64.
31  EXPECT_EQ(capacity, 64u);
32 
33  auto const [pool2, capacity_2] =
34  context->GetDescriptorPoolRecycler()->Get(1023);
35 
36  // Rounds up to the next power of two.
37  EXPECT_EQ(capacity_2, 1024u);
38 
39  context->Shutdown();
40 }

◆ TEST() [83/299]

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(1024);
18  auto const [pool2, __] = context->GetDescriptorPoolRecycler()->Get(1024);
19 
20  // The two descriptor pools should be different.
21  EXPECT_NE(pool1.get(), pool2.get());
22 
23  context->Shutdown();
24 }

◆ TEST() [84/299]

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

Definition at line 101 of file descriptor_pool_vk_unittests.cc.

101  {
102  auto const context = MockVulkanContextBuilder().Build();
103 
104  // Create 33 pools
105  {
106  std::vector<std::unique_ptr<DescriptorPoolVK>> pools;
107  for (auto i = 0u; i < 33; i++) {
108  auto pool = std::make_unique<DescriptorPoolVK>(context);
109  pool->AllocateDescriptorSets(1024, 1024, 1024, {});
110  pools.push_back(std::move(pool));
111  }
112  }
113 
114  // See note above.
115  for (auto i = 0u; i < 2; i++) {
116  auto waiter = fml::AutoResetWaitableEvent();
117  auto rattle = DeathRattle([&waiter]() { waiter.Signal(); });
118  {
119  UniqueResourceVKT<DeathRattle> resource(context->GetResourceManager(),
120  std::move(rattle));
121  }
122  waiter.Wait();
123  }
124 
125  auto const called = GetMockVulkanFunctions(context->GetDevice());
126  EXPECT_EQ(
127  std::count(called->begin(), called->end(), "vkCreateDescriptorPool"),
128  33u);
129  EXPECT_EQ(std::count(called->begin(), called->end(), "vkResetDescriptorPool"),
130  33u);
131 
132  // Now create 33 more descriptor pools and observe that only one more is
133  // allocated.
134  {
135  std::vector<std::unique_ptr<DescriptorPoolVK>> pools;
136  for (auto i = 0u; i < 33; i++) {
137  auto pool = std::make_unique<DescriptorPoolVK>(context);
138  pool->AllocateDescriptorSets(1024, 1024, 1024, {});
139  pools.push_back(std::move(pool));
140  }
141  }
142 
143  for (auto i = 0u; i < 2; i++) {
144  auto waiter = fml::AutoResetWaitableEvent();
145  auto rattle = DeathRattle([&waiter]() { waiter.Signal(); });
146  {
147  UniqueResourceVKT<DeathRattle> resource(context->GetResourceManager(),
148  std::move(rattle));
149  }
150  waiter.Wait();
151  }
152 
153  auto const called_twice = GetMockVulkanFunctions(context->GetDevice());
154  // 32 of the descriptor pools were recycled, so only one more is created.
155  EXPECT_EQ(
156  std::count(called->begin(), called->end(), "vkCreateDescriptorPool"),
157  34u);
158 
159  context->Shutdown();
160 }

◆ TEST() [85/299]

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

Definition at line 63 of file descriptor_pool_vk_unittests.cc.

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

◆ TEST() [86/299]

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

Definition at line 67 of file directional_gaussian_blur_filter_contents_unittests.cc.

67  {
68  Scalar sigma_radius_1 = CalculateSigmaForBlurRadius(1.0);
69  auto contents = std::make_unique<DirectionalGaussianBlurFilterContents>();
70  contents->SetSigma(Sigma{sigma_radius_1});
71  contents->SetDirection({1.0, 0.0});
72  std::optional<Rect> coverage = contents->GetFilterSourceCoverage(
73  /*effect_transform=*/Matrix::MakeScale({2.0, 2.0, 1.0}),
74  /*output_limit=*/Rect::MakeLTRB(100, 100, 200, 200));
75  ASSERT_EQ(coverage, Rect::MakeLTRB(100 - 2, 100, 200 + 2, 200));
76 }

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

◆ TEST() [87/299]

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

Definition at line 1785 of file dl_unittests.cc.

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

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

◆ TEST() [88/299]

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

Definition at line 1762 of file dl_unittests.cc.

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

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

◆ TEST() [89/299]

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

Definition at line 20 of file geometry_unittests.cc.

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

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

◆ TEST() [90/299]

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

Definition at line 30 of file geometry_unittests.cc.

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

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

◆ TEST() [91/299]

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

Definition at line 39 of file geometry_unittests.cc.

39  {
40  {
41  auto geometry = Geometry::MakeLine({10, 10}, {20, 10}, 2, Cap::kButt);
42  EXPECT_EQ(geometry->GetCoverage({}), Rect::MakeLTRB(10, 9, 20, 11));
43  EXPECT_TRUE(geometry->CoversArea({}, Rect::MakeLTRB(10, 9, 20, 11)));
44  }
45 
46  {
47  auto geometry = Geometry::MakeLine({10, 10}, {20, 10}, 2, Cap::kSquare);
48  EXPECT_EQ(geometry->GetCoverage({}), Rect::MakeLTRB(9, 9, 21, 11));
49  EXPECT_TRUE(geometry->CoversArea({}, Rect::MakeLTRB(9, 9, 21, 11)));
50  }
51 
52  {
53  auto geometry = Geometry::MakeLine({10, 10}, {10, 20}, 2, Cap::kButt);
54  EXPECT_EQ(geometry->GetCoverage({}), Rect::MakeLTRB(9, 10, 11, 20));
55  EXPECT_TRUE(geometry->CoversArea({}, Rect::MakeLTRB(9, 10, 11, 20)));
56  }
57 
58  {
59  auto geometry = Geometry::MakeLine({10, 10}, {10, 20}, 2, Cap::kSquare);
60  EXPECT_EQ(geometry->GetCoverage({}), Rect::MakeLTRB(9, 9, 11, 21));
61  EXPECT_TRUE(geometry->CoversArea({}, Rect::MakeLTRB(9, 9, 11, 21)));
62  }
63 }

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

◆ TEST() [92/299]

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

Definition at line 12 of file geometry_unittests.cc.

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

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

◆ TEST() [93/299]

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

Definition at line 65 of file geometry_unittests.cc.

65  {
66  auto geometry =
67  Geometry::MakeRoundRect(Rect::MakeLTRB(0, 0, 100, 100), Size(20, 20));
68  EXPECT_FALSE(geometry->CoversArea({}, Rect::MakeLTRB(15, 15, 85, 85)));
69  EXPECT_TRUE(geometry->CoversArea({}, Rect::MakeLTRB(20, 20, 80, 80)));
70  EXPECT_TRUE(geometry->CoversArea({}, Rect::MakeLTRB(30, 1, 70, 99)));
71  EXPECT_TRUE(geometry->CoversArea({}, Rect::MakeLTRB(1, 30, 99, 70)));
72 }

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

◆ TEST() [94/299]

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

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

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

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

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

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

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

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

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

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

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

Definition at line 375 of file gaussian_blur_filter_contents_unittests.cc.

375  {
376  Scalar sigma = 1.0;
377  Scalar radius = GaussianBlurFilterContents::CalculateBlurRadius(
379  Scalar derived_sigma = CalculateSigmaForBlurRadius(radius);
380 
381  EXPECT_NEAR(sigma, derived_sigma, 0.01f);
382 }

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

◆ TEST() [105/299]

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

Definition at line 167 of file gaussian_blur_filter_contents_unittests.cc.

167  {
168  EXPECT_EQ(GaussianBlurFilterContents::CalculateScale(1.0f), 1);
169  EXPECT_EQ(GaussianBlurFilterContents::CalculateScale(2.0f), 1);
170  EXPECT_EQ(GaussianBlurFilterContents::CalculateScale(3.0f), 1);
171  EXPECT_EQ(GaussianBlurFilterContents::CalculateScale(4.0f), 1);
172  EXPECT_EQ(GaussianBlurFilterContents::CalculateScale(16.0f), 0.25);
173  EXPECT_EQ(GaussianBlurFilterContents::CalculateScale(1024.0f), 4.f / 1024.f);
174 }

References impeller::GaussianBlurFilterContents::CalculateScale().

◆ TEST() [106/299]

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

Definition at line 384 of file gaussian_blur_filter_contents_unittests.cc.

384  {
385  BlurParameters parameters = {.blur_uv_offset = Point(1, 0),
386  .blur_sigma = 1,
387  .blur_radius = 5,
388  .step_size = 1};
389  KernelPipeline::FragmentShader::KernelSamples samples =
390  GenerateBlurInfo(parameters);
391  EXPECT_EQ(samples.sample_count, 11);
392 
393  // Coefficients should add up to 1.
394  Scalar tally = 0;
395  for (int i = 0; i < samples.sample_count; ++i) {
396  tally += samples.samples[i].coefficient;
397  }
398  EXPECT_FLOAT_EQ(tally, 1.0f);
399 
400  // Verify the shape of the curve.
401  for (int i = 0; i < 5; ++i) {
402  EXPECT_FLOAT_EQ(samples.samples[i].coefficient,
403  samples.samples[10 - i].coefficient);
404  EXPECT_TRUE(samples.samples[i + 1].coefficient >
405  samples.samples[i].coefficient);
406  }
407 }

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

◆ TEST() [107/299]

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

Definition at line 71 of file gaussian_blur_filter_contents_unittests.cc.

71  {
72  GaussianBlurFilterContents contents(/*sigma_x=*/0.0, /*sigma_y=*/0.0,
73  Entity::TileMode::kDecal);
74  FilterInput::Vector inputs = {};
75  Entity entity;
76  std::optional<Rect> coverage =
77  contents.GetFilterCoverage(inputs, entity, /*effect_transform=*/Matrix());
78  ASSERT_FALSE(coverage.has_value());
79 }

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

◆ TEST() [108/299]

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

Definition at line 81 of file gaussian_blur_filter_contents_unittests.cc.

81  {
82  GaussianBlurFilterContents contents(/*sigma_x=*/0.0, /*sigma_y=*/0.0,
83  Entity::TileMode::kDecal);
84  FilterInput::Vector inputs = {
85  FilterInput::Make(Rect::MakeLTRB(10, 10, 110, 110))};
86  Entity entity;
87  std::optional<Rect> coverage =
88  contents.GetFilterCoverage(inputs, entity, /*effect_transform=*/Matrix());
89  ASSERT_EQ(coverage, Rect::MakeLTRB(10, 10, 110, 110));
90 }

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

◆ TEST() [109/299]

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

Definition at line 92 of file gaussian_blur_filter_contents_unittests.cc.

92  {
93  Scalar sigma_radius_1 = CalculateSigmaForBlurRadius(1.0);
94  GaussianBlurFilterContents contents(/*sigma_x=*/sigma_radius_1,
95  /*sigma_y=*/sigma_radius_1,
96  Entity::TileMode::kDecal);
97  FilterInput::Vector inputs = {
98  FilterInput::Make(Rect::MakeLTRB(100, 100, 200, 200))};
99  Entity entity;
100  std::optional<Rect> coverage =
101  contents.GetFilterCoverage(inputs, entity, /*effect_transform=*/Matrix());
102  EXPECT_TRUE(coverage.has_value());
103  if (coverage.has_value()) {
104  EXPECT_RECT_NEAR(coverage.value(), Rect::MakeLTRB(99, 99, 201, 201));
105  }
106 }

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

◆ TEST() [110/299]

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

Definition at line 64 of file gaussian_blur_filter_contents_unittests.cc.

64  {
65  GaussianBlurFilterContents contents(/*sigma_x=*/0.0, /*sigma_y=*/0.0,
66  Entity::TileMode::kDecal);
67  EXPECT_EQ(contents.GetSigmaX(), 0.0);
68  EXPECT_EQ(contents.GetSigmaY(), 0.0);
69 }

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

◆ TEST() [111/299]

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

Definition at line 157 of file gaussian_blur_filter_contents_unittests.cc.

157  {
158  Scalar sigma_radius_1 = CalculateSigmaForBlurRadius(1.0);
159  auto contents = std::make_unique<GaussianBlurFilterContents>(
160  sigma_radius_1, sigma_radius_1, Entity::TileMode::kDecal);
161  std::optional<Rect> coverage = contents->GetFilterSourceCoverage(
162  /*effect_transform=*/Matrix::MakeScale({2.0, 2.0, 1.0}),
163  /*output_limit=*/Rect::MakeLTRB(100, 100, 200, 200));
164  ASSERT_EQ(coverage, Rect::MakeLTRB(100 - 2, 100 - 2, 200 + 2, 200 + 2));
165 }

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

◆ TEST() [112/299]

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

Definition at line 1452 of file geometry_unittests.cc.

1452  {
1453  using BlendT = std::underlying_type_t<BlendMode>;
1454  for (BlendT i = 0; i <= static_cast<BlendT>(BlendMode::kLast); i++) {
1455  auto mode = static_cast<BlendMode>(i);
1456  auto result = BlendModeToString(mode);
1458  }
1459 }

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

◆ TEST() [113/299]

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

Definition at line 1461 of file geometry_unittests.cc.

1461  {
1462  {
1463  auto deg = Degrees{90.0};
1464  Radians rad = deg;
1465  ASSERT_FLOAT_EQ(rad.radians, kPiOver2);
1466  }
1467 }

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

◆ TEST() [114/299]

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

Definition at line 604 of file geometry_unittests.cc.

604  {
605  {
606  Point p1(1.0, 2.0);
607  IPoint p2 = static_cast<IPoint>(p1);
608  ASSERT_EQ(p2.x, 1u);
609  ASSERT_EQ(p2.y, 2u);
610  }
611 
612  {
613  Size s1(1.0, 2.0);
614  ISize s2 = static_cast<ISize>(s1);
615  ASSERT_EQ(s2.width, 1u);
616  ASSERT_EQ(s2.height, 2u);
617  }
618 
619  {
620  Size s1(1.0, 2.0);
621  Point p1 = static_cast<Point>(s1);
622  ASSERT_EQ(p1.x, 1u);
623  ASSERT_EQ(p1.y, 2u);
624  }
625 
626  {
627  Rect r1 = Rect::MakeXYWH(1.0, 2.0, 3.0, 4.0);
628  IRect r2 = static_cast<IRect>(r1);
629  ASSERT_EQ(r2.GetOrigin().x, 1u);
630  ASSERT_EQ(r2.GetOrigin().y, 2u);
631  ASSERT_EQ(r2.GetSize().width, 3u);
632  ASSERT_EQ(r2.GetSize().height, 4u);
633  ASSERT_EQ(r2.GetX(), 1u);
634  ASSERT_EQ(r2.GetY(), 2u);
635  ASSERT_EQ(r2.GetWidth(), 3u);
636  ASSERT_EQ(r2.GetHeight(), 4u);
637  }
638 }

References impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetOrigin(), impeller::TRect< T >::GetSize(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetY(), impeller::TSize< T >::height, impeller::TRect< Scalar >::MakeXYWH(), impeller::TSize< T >::width, impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ TEST() [115/299]

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

Definition at line 591 of file geometry_unittests.cc.

591  {
592  ASSERT_EQ((Size{128, 128}.MipCount()), 7u);
593  ASSERT_EQ((Size{128, 256}.MipCount()), 8u);
594  ASSERT_EQ((Size{128, 130}.MipCount()), 8u);
595  ASSERT_EQ((Size{128, 257}.MipCount()), 9u);
596  ASSERT_EQ((Size{257, 128}.MipCount()), 9u);
597  ASSERT_EQ((Size{128, 0}.MipCount()), 1u);
598  ASSERT_EQ((Size{128, -25}.MipCount()), 1u);
599  ASSERT_EQ((Size{-128, 25}.MipCount()), 1u);
600  ASSERT_EQ((Size{1, 1}.MipCount()), 1u);
601  ASSERT_EQ((Size{0, 0}.MipCount()), 1u);
602 }

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

◆ TEST() [116/299]

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

Definition at line 640 of file geometry_unittests.cc.

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

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

◆ TEST() [117/299]

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

Definition at line 670 of file geometry_unittests.cc.

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

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

◆ TEST() [118/299]

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

Definition at line 1174 of file geometry_unittests.cc.

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

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

◆ TEST() [119/299]

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

Definition at line 1208 of file geometry_unittests.cc.

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

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

◆ TEST() [120/299]

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

Definition at line 822 of file geometry_unittests.cc.

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

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

◆ TEST() [121/299]

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

Definition at line 1124 of file geometry_unittests.cc.

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

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

◆ TEST() [122/299]

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

Definition at line 1381 of file geometry_unittests.cc.

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

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

◆ TEST() [123/299]

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

Definition at line 1341 of file geometry_unittests.cc.

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

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

◆ TEST() [124/299]

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

Definition at line 1319 of file geometry_unittests.cc.

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

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

◆ TEST() [125/299]

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

Definition at line 1407 of file geometry_unittests.cc.

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

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

◆ TEST() [126/299]

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

Definition at line 1361 of file geometry_unittests.cc.

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

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

◆ TEST() [127/299]

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

Definition at line 1276 of file geometry_unittests.cc.

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

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

◆ TEST() [128/299]

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

Definition at line 2061 of file geometry_unittests.cc.

2061  {
2062  {
2063  std::stringstream stream;
2064  Color m;
2065  stream << m;
2066  ASSERT_EQ(stream.str(), "(0, 0, 0, 0)");
2067  }
2068 
2069  {
2070  std::stringstream stream;
2071  Color m(1, 2, 3, 4);
2072  stream << m;
2073  ASSERT_EQ(stream.str(), "(1, 2, 3, 4)");
2074  }
2075 }

◆ TEST() [129/299]

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

Definition at line 1299 of file geometry_unittests.cc.

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

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

◆ TEST() [130/299]

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

Definition at line 1427 of file geometry_unittests.cc.

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

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

◆ TEST() [131/299]

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

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

Definition at line 2083 of file geometry_unittests.cc.

2083  {
2084  {
2085  // Simple 2 color gradient produces color buffer containing exactly those
2086  // values.
2087  std::vector<Color> colors = {Color::Red(), Color::Blue()};
2088  std::vector<Scalar> stops = {0.0, 1.0};
2089 
2090  auto gradient = CreateGradientBuffer(colors, stops);
2091 
2092  ASSERT_COLOR_BUFFER_NEAR(gradient.color_bytes, colors);
2093  ASSERT_EQ(gradient.texture_size, 2u);
2094  }
2095 
2096  {
2097  // Gradient with duplicate stops does not create an empty texture.
2098  std::vector<Color> colors = {Color::Red(), Color::Yellow(), Color::Black(),
2099  Color::Blue()};
2100  std::vector<Scalar> stops = {0.0, 0.25, 0.25, 1.0};
2101 
2102  auto gradient = CreateGradientBuffer(colors, stops);
2103  ASSERT_EQ(gradient.texture_size, 5u);
2104  }
2105 
2106  {
2107  // Simple N color gradient produces color buffer containing exactly those
2108  // values.
2109  std::vector<Color> colors = {Color::Red(), Color::Blue(), Color::Green(),
2110  Color::White()};
2111  std::vector<Scalar> stops = {0.0, 0.33, 0.66, 1.0};
2112 
2113  auto gradient = CreateGradientBuffer(colors, stops);
2114 
2115  ASSERT_COLOR_BUFFER_NEAR(gradient.color_bytes, colors);
2116  ASSERT_EQ(gradient.texture_size, 4u);
2117  }
2118 
2119  {
2120  // Gradient with color stops will lerp and scale buffer.
2121  std::vector<Color> colors = {Color::Red(), Color::Blue(), Color::Green()};
2122  std::vector<Scalar> stops = {0.0, 0.25, 1.0};
2123 
2124  auto gradient = CreateGradientBuffer(colors, stops);
2125 
2126  std::vector<Color> lerped_colors = {
2127  Color::Red(),
2128  Color::Blue(),
2129  Color::Lerp(Color::Blue(), Color::Green(), 0.3333),
2130  Color::Lerp(Color::Blue(), Color::Green(), 0.6666),
2131  Color::Green(),
2132  };
2133  ASSERT_COLOR_BUFFER_NEAR(gradient.color_bytes, lerped_colors);
2134  ASSERT_EQ(gradient.texture_size, 5u);
2135  }
2136 
2137  {
2138  // Gradient size is capped at 1024.
2139  std::vector<Color> colors = {};
2140  std::vector<Scalar> stops = {};
2141  for (auto i = 0u; i < 1025; i++) {
2142  colors.push_back(Color::Blue());
2143  stops.push_back(i / 1025.0);
2144  }
2145 
2146  auto gradient = CreateGradientBuffer(colors, stops);
2147 
2148  ASSERT_EQ(gradient.texture_size, 1024u);
2149  ASSERT_EQ(gradient.color_bytes.size(), 1024u * 4);
2150  }
2151 }

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

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

Definition at line 2153 of file geometry_unittests.cc.

2153  {
2154 #ifdef FML_OS_WIN
2155  GTEST_SKIP() << "Half-precision floats (IEEE 754) are not portable and "
2156  "unavailable on Windows.";
2157 #else
2158  ASSERT_EQ(ScalarToHalf(0.0), 0.0f16);
2159  ASSERT_EQ(ScalarToHalf(0.05), 0.05f16);
2160  ASSERT_EQ(ScalarToHalf(2.43), 2.43f16);
2161  ASSERT_EQ(ScalarToHalf(-1.45), -1.45f16);
2162 
2163  // 65504 is the largest possible half.
2164  ASSERT_EQ(ScalarToHalf(65504.0f), 65504.0f16);
2165  ASSERT_EQ(ScalarToHalf(65504.0f + 1), 65504.0f16);
2166 
2167  // Colors
2168  ASSERT_EQ(HalfVector4(Color::Red()),
2169  HalfVector4(1.0f16, 0.0f16, 0.0f16, 1.0f16));
2170  ASSERT_EQ(HalfVector4(Color::Green()),
2171  HalfVector4(0.0f16, 1.0f16, 0.0f16, 1.0f16));
2172  ASSERT_EQ(HalfVector4(Color::Blue()),
2173  HalfVector4(0.0f16, 0.0f16, 1.0f16, 1.0f16));
2174  ASSERT_EQ(HalfVector4(Color::Black().WithAlpha(0)),
2175  HalfVector4(0.0f16, 0.0f16, 0.0f16, 0.0f16));
2176 
2177  ASSERT_EQ(HalfVector3(Vector3(4.0, 6.0, -1.0)),
2178  HalfVector3(4.0f16, 6.0f16, -1.0f16));
2179  ASSERT_EQ(HalfVector2(Vector2(4.0, 6.0)), HalfVector2(4.0f16, 6.0f16));
2180 
2181  ASSERT_EQ(Half(0.5f), Half(0.5f16));
2182  ASSERT_EQ(Half(0.5), Half(0.5f16));
2183  ASSERT_EQ(Half(5), Half(5.0f16));
2184 #endif // FML_OS_WIN
2185 }

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

◆ TEST() [134/299]

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

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(), and impeller::Matrix::MakeScale().

◆ TEST() [136/299]

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

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

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

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

Definition at line 405 of file geometry_unittests.cc.

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

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

◆ TEST() [140/299]

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

Definition at line 429 of file geometry_unittests.cc.

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

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

◆ TEST() [141/299]

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

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 }

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

◆ TEST() [143/299]

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

Definition at line 452 of file geometry_unittests.cc.

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

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

◆ TEST() [144/299]

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

Definition at line 492 of file geometry_unittests.cc.

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

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

◆ TEST() [145/299]

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

Definition at line 357 of file geometry_unittests.cc.

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

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

◆ TEST() [146/299]

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

Definition at line 381 of file geometry_unittests.cc.

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

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

◆ TEST() [147/299]

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

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

Definition at line 1986 of file geometry_unittests.cc.

1986  {
1987  {
1988  std::stringstream stream;
1989  Matrix m;
1990  stream << m;
1991  ASSERT_EQ(stream.str(), R"((
1992  1.000000, 0.000000, 0.000000, 0.000000,
1993  0.000000, 1.000000, 0.000000, 0.000000,
1994  0.000000, 0.000000, 1.000000, 0.000000,
1995  0.000000, 0.000000, 0.000000, 1.000000,
1996 ))");
1997  }
1998 
1999  {
2000  std::stringstream stream;
2001  Matrix m = Matrix::MakeTranslation(Vector3(10, 20, 30));
2002  stream << m;
2003 
2004  ASSERT_EQ(stream.str(), R"((
2005  1.000000, 0.000000, 0.000000, 10.000000,
2006  0.000000, 1.000000, 0.000000, 20.000000,
2007  0.000000, 0.000000, 1.000000, 30.000000,
2008  0.000000, 0.000000, 0.000000, 1.000000,
2009 ))");
2010  }
2011 }

References impeller::Matrix::MakeTranslation().

◆ TEST() [149/299]

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

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

Definition at line 466 of file geometry_unittests.cc.

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

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

◆ TEST() [151/299]

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

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

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

Definition at line 1604 of file geometry_unittests.cc.

1604  {
1605  Rect a = Rect::MakeLTRB(0, 0, 110, 110);
1606  Rect b = Rect::MakeLTRB(100, 100, 200, 200);
1607  Rect c = Rect::MakeLTRB(100, 0, 200, 110);
1608 
1609  // NullOpt, NullOpt
1610  EXPECT_FALSE(Rect::Intersection(std::nullopt, std::nullopt).has_value());
1611  EXPECT_EQ(Rect::Intersection(std::nullopt, std::nullopt), std::nullopt);
1612 
1613  auto test1 = [](const Rect& r) {
1614  // Rect, NullOpt
1615  EXPECT_TRUE(Rect::Intersection(r, std::nullopt).has_value());
1616  EXPECT_EQ(Rect::Intersection(r, std::nullopt).value(), r);
1617 
1618  // OptRect, NullOpt
1619  EXPECT_TRUE(Rect::Intersection(std::optional(r), std::nullopt).has_value());
1620  EXPECT_EQ(Rect::Intersection(std::optional(r), std::nullopt).value(), r);
1621 
1622  // NullOpt, Rect
1623  EXPECT_TRUE(Rect::Intersection(std::nullopt, r).has_value());
1624  EXPECT_EQ(Rect::Intersection(std::nullopt, r).value(), r);
1625 
1626  // NullOpt, OptRect
1627  EXPECT_TRUE(Rect::Intersection(std::nullopt, std::optional(r)).has_value());
1628  EXPECT_EQ(Rect::Intersection(std::nullopt, std::optional(r)).value(), r);
1629  };
1630 
1631  test1(a);
1632  test1(b);
1633  test1(c);
1634 
1635  auto test2 = [](const Rect& a, const Rect& b, const Rect& i) {
1636  ASSERT_EQ(a.Intersection(b), i);
1637 
1638  // Rect, OptRect
1639  EXPECT_TRUE(Rect::Intersection(a, std::optional(b)).has_value());
1640  EXPECT_EQ(Rect::Intersection(a, std::optional(b)).value(), i);
1641 
1642  // OptRect, Rect
1643  EXPECT_TRUE(Rect::Intersection(std::optional(a), b).has_value());
1644  EXPECT_EQ(Rect::Intersection(std::optional(a), b).value(), i);
1645 
1646  // OptRect, OptRect
1647  EXPECT_TRUE(
1648  Rect::Intersection(std::optional(a), std::optional(b)).has_value());
1649  EXPECT_EQ(Rect::Intersection(std::optional(a), std::optional(b)).value(),
1650  i);
1651  };
1652 
1653  test2(a, b, Rect::MakeLTRB(100, 100, 110, 110));
1654  test2(a, c, Rect::MakeLTRB(100, 0, 110, 110));
1655  test2(b, c, Rect::MakeLTRB(100, 100, 200, 110));
1656 }

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

◆ TEST() [154/299]

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

Definition at line 1503 of file geometry_unittests.cc.

1503  {
1504  Rect a = Rect::MakeLTRB(0, 0, 100, 100);
1505  Rect b = Rect::MakeLTRB(100, 100, 200, 200);
1506  Rect c = Rect::MakeLTRB(100, 0, 200, 100);
1507 
1508  // NullOpt, NullOpt
1509  EXPECT_FALSE(Rect::Union(std::nullopt, std::nullopt).has_value());
1510  EXPECT_EQ(Rect::Union(std::nullopt, std::nullopt), std::nullopt);
1511 
1512  auto test1 = [](const Rect& r) {
1513  // Rect, NullOpt
1514  EXPECT_TRUE(Rect::Union(r, std::nullopt).has_value());
1515  EXPECT_EQ(Rect::Union(r, std::nullopt).value(), r);
1516 
1517  // OptRect, NullOpt
1518  EXPECT_TRUE(Rect::Union(std::optional(r), std::nullopt).has_value());
1519  EXPECT_EQ(Rect::Union(std::optional(r), std::nullopt).value(), r);
1520 
1521  // NullOpt, Rect
1522  EXPECT_TRUE(Rect::Union(std::nullopt, r).has_value());
1523  EXPECT_EQ(Rect::Union(std::nullopt, r).value(), r);
1524 
1525  // NullOpt, OptRect
1526  EXPECT_TRUE(Rect::Union(std::nullopt, std::optional(r)).has_value());
1527  EXPECT_EQ(Rect::Union(std::nullopt, std::optional(r)).value(), r);
1528  };
1529 
1530  test1(a);
1531  test1(b);
1532  test1(c);
1533 
1534  auto test2 = [](const Rect& a, const Rect& b, const Rect& u) {
1535  ASSERT_EQ(a.Union(b), u);
1536 
1537  // Rect, OptRect
1538  EXPECT_TRUE(Rect::Union(a, std::optional(b)).has_value());
1539  EXPECT_EQ(Rect::Union(a, std::optional(b)).value(), u);
1540 
1541  // OptRect, Rect
1542  EXPECT_TRUE(Rect::Union(std::optional(a), b).has_value());
1543  EXPECT_EQ(Rect::Union(std::optional(a), b).value(), u);
1544 
1545  // OptRect, OptRect
1546  EXPECT_TRUE(Rect::Union(std::optional(a), std::optional(b)).has_value());
1547  EXPECT_EQ(Rect::Union(std::optional(a), std::optional(b)).value(), u);
1548  };
1549 
1550  test2(a, b, Rect::MakeLTRB(0, 0, 200, 200));
1551  test2(a, c, Rect::MakeLTRB(0, 0, 200, 100));
1552  test2(b, c, Rect::MakeLTRB(100, 0, 200, 200));
1553 }

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

◆ TEST() [155/299]

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

Definition at line 962 of file geometry_unittests.cc.

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

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

◆ TEST() [156/299]

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

Definition at line 969 of file geometry_unittests.cc.

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

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

◆ TEST() [157/299]

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

Definition at line 1061 of file geometry_unittests.cc.

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

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

◆ TEST() [158/299]

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

Definition at line 917 of file geometry_unittests.cc.

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

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

◆ TEST() [159/299]

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

Definition at line 897 of file geometry_unittests.cc.

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

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

◆ TEST() [160/299]

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

Definition at line 1040 of file geometry_unittests.cc.

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

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

◆ TEST() [161/299]

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

Definition at line 702 of file geometry_unittests.cc.

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

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

◆ TEST() [162/299]

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

Definition at line 1103 of file geometry_unittests.cc.

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

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

◆ TEST() [163/299]

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

Definition at line 1019 of file geometry_unittests.cc.

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

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

◆ TEST() [164/299]

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

Definition at line 998 of file geometry_unittests.cc.

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

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

◆ TEST() [165/299]

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

Definition at line 2013 of file geometry_unittests.cc.

2013  {
2014  {
2015  std::stringstream stream;
2016  Point m;
2017  stream << m;
2018  ASSERT_EQ(stream.str(), "(0, 0)");
2019  }
2020 
2021  {
2022  std::stringstream stream;
2023  Point m(13, 37);
2024  stream << m;
2025  ASSERT_EQ(stream.str(), "(13, 37)");
2026  }
2027 }

◆ TEST() [166/299]

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

Definition at line 937 of file geometry_unittests.cc.

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

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

◆ TEST() [167/299]

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

Definition at line 1082 of file geometry_unittests.cc.

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

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

◆ TEST() [168/299]

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

Definition at line 538 of file geometry_unittests.cc.

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

References ASSERT_QUATERNION_NEAR, and impeller::kPiOver4.

◆ TEST() [169/299]

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

Definition at line 549 of file geometry_unittests.cc.

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

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

◆ TEST() [170/299]

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

Definition at line 1755 of file geometry_unittests.cc.

1755  {
1756  {
1757  // Origin is inclusive
1758  Rect r = Rect::MakeXYWH(100, 100, 100, 100);
1759  Point p(100, 100);
1760  ASSERT_TRUE(r.Contains(p));
1761  }
1762  {
1763  // Size is exclusive
1764  Rect r = Rect::MakeXYWH(100, 100, 100, 100);
1765  Point p(200, 200);
1766  ASSERT_FALSE(r.Contains(p));
1767  }
1768  {
1769  Rect r = Rect::MakeXYWH(100, 100, 100, 100);
1770  Point p(99, 99);
1771  ASSERT_FALSE(r.Contains(p));
1772  }
1773  {
1774  Rect r = Rect::MakeXYWH(100, 100, 100, 100);
1775  Point p(199, 199);
1776  ASSERT_TRUE(r.Contains(p));
1777  }
1778 
1779  {
1780  Rect r = Rect::MakeMaximum();
1781  Point p(199, 199);
1782  ASSERT_TRUE(r.Contains(p));
1783  }
1784 }

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

◆ TEST() [171/299]

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

Definition at line 1786 of file geometry_unittests.cc.

1786  {
1787  {
1788  Rect a = Rect::MakeXYWH(100, 100, 100, 100);
1789  ASSERT_TRUE(a.Contains(a));
1790  }
1791  {
1792  Rect a = Rect::MakeXYWH(100, 100, 100, 100);
1793  Rect b = Rect::MakeXYWH(0, 0, 0, 0);
1794  ASSERT_FALSE(a.Contains(b));
1795  }
1796  {
1797  Rect a = Rect::MakeXYWH(100, 100, 100, 100);
1798  Rect b = Rect::MakeXYWH(150, 150, 20, 20);
1799  ASSERT_TRUE(a.Contains(b));
1800  }
1801  {
1802  Rect a = Rect::MakeXYWH(100, 100, 100, 100);
1803  Rect b = Rect::MakeXYWH(150, 150, 100, 100);
1804  ASSERT_FALSE(a.Contains(b));
1805  }
1806  {
1807  Rect a = Rect::MakeXYWH(100, 100, 100, 100);
1808  Rect b = Rect::MakeXYWH(50, 50, 100, 100);
1809  ASSERT_FALSE(a.Contains(b));
1810  }
1811  {
1812  Rect a = Rect::MakeXYWH(100, 100, 100, 100);
1813  Rect b = Rect::MakeXYWH(0, 0, 300, 300);
1814  ASSERT_FALSE(a.Contains(b));
1815  }
1816  {
1817  Rect a = Rect::MakeMaximum();
1818  Rect b = Rect::MakeXYWH(0, 0, 300, 300);
1819  ASSERT_TRUE(a.Contains(b));
1820  }
1821 }

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

◆ TEST() [172/299]

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

Definition at line 1696 of file geometry_unittests.cc.

1696  {
1697  // No cutout.
1698  {
1699  Rect a = Rect::MakeXYWH(0, 0, 100, 100);
1700  Rect b = Rect::MakeXYWH(0, 0, 50, 50);
1701  auto u = a.Cutout(b);
1702  ASSERT_TRUE(u.has_value());
1703  ASSERT_RECT_NEAR(u.value(), a);
1704  }
1705 
1706  // Full cutout.
1707  {
1708  Rect a = Rect::MakeXYWH(0, 0, 100, 100);
1709  Rect b = Rect::MakeXYWH(-10, -10, 120, 120);
1710  auto u = a.Cutout(b);
1711  ASSERT_FALSE(u.has_value());
1712  }
1713 
1714  // Cutout from top.
1715  {
1716  auto a = Rect::MakeLTRB(0, 0, 100, 100);
1717  auto b = Rect::MakeLTRB(-10, -10, 110, 90);
1718  auto u = a.Cutout(b);
1719  auto expected = Rect::MakeLTRB(0, 90, 100, 100);
1720  ASSERT_TRUE(u.has_value());
1721  ASSERT_RECT_NEAR(u.value(), expected);
1722  }
1723 
1724  // Cutout from bottom.
1725  {
1726  auto a = Rect::MakeLTRB(0, 0, 100, 100);
1727  auto b = Rect::MakeLTRB(-10, 10, 110, 110);
1728  auto u = a.Cutout(b);
1729  auto expected = Rect::MakeLTRB(0, 0, 100, 10);
1730  ASSERT_TRUE(u.has_value());
1731  ASSERT_RECT_NEAR(u.value(), expected);
1732  }
1733 
1734  // Cutout from left.
1735  {
1736  auto a = Rect::MakeLTRB(0, 0, 100, 100);
1737  auto b = Rect::MakeLTRB(-10, -10, 90, 110);
1738  auto u = a.Cutout(b);
1739  auto expected = Rect::MakeLTRB(90, 0, 100, 100);
1740  ASSERT_TRUE(u.has_value());
1741  ASSERT_RECT_NEAR(u.value(), expected);
1742  }
1743 
1744  // Cutout from right.
1745  {
1746  auto a = Rect::MakeLTRB(0, 0, 100, 100);
1747  auto b = Rect::MakeLTRB(10, -10, 110, 110);
1748  auto u = a.Cutout(b);
1749  auto expected = Rect::MakeLTRB(0, 0, 10, 100);
1750  ASSERT_TRUE(u.has_value());
1751  ASSERT_RECT_NEAR(u.value(), expected);
1752  }
1753 }

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

◆ TEST() [173/299]

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

Definition at line 1946 of file geometry_unittests.cc.

1946  {
1947  auto r = Rect::MakeLTRB(1, 2, 3, 4);
1948 
1949  ASSERT_EQ(r.GetLeft(), 1);
1950  ASSERT_EQ(r.GetTop(), 2);
1951  ASSERT_EQ(r.GetRight(), 3);
1952  ASSERT_EQ(r.GetBottom(), 4);
1953 
1954  ASSERT_POINT_NEAR(r.GetLeftTop(), Point(1, 2));
1955  ASSERT_POINT_NEAR(r.GetRightTop(), Point(3, 2));
1956  ASSERT_POINT_NEAR(r.GetLeftBottom(), Point(1, 4));
1957  ASSERT_POINT_NEAR(r.GetRightBottom(), Point(3, 4));
1958 }

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

◆ TEST() [174/299]

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

Definition at line 1877 of file geometry_unittests.cc.

1877  {
1878  {
1879  auto a = Rect::MakeLTRB(100, 100, 200, 200);
1880  auto b = a.Expand(1);
1881  auto expected = Rect::MakeLTRB(99, 99, 201, 201);
1882  ASSERT_RECT_NEAR(b, expected);
1883  }
1884  {
1885  auto a = Rect::MakeLTRB(100, 100, 200, 200);
1886  auto b = a.Expand(-1);
1887  auto expected = Rect::MakeLTRB(101, 101, 199, 199);
1888  ASSERT_RECT_NEAR(b, expected);
1889  }
1890 
1891  {
1892  auto a = Rect::MakeLTRB(100, 100, 200, 200);
1893  auto b = a.Expand(1, 2, 3, 4);
1894  auto expected = Rect::MakeLTRB(99, 98, 203, 204);
1895  ASSERT_RECT_NEAR(b, expected);
1896  }
1897  {
1898  auto a = Rect::MakeLTRB(100, 100, 200, 200);
1899  auto b = a.Expand(-1, -2, -3, -4);
1900  auto expected = Rect::MakeLTRB(101, 102, 197, 196);
1901  ASSERT_RECT_NEAR(b, expected);
1902  }
1903 }

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

◆ TEST() [175/299]

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

Definition at line 1823 of file geometry_unittests.cc.

1823  {
1824  {
1825  Rect r = Rect::MakeXYWH(100, 200, 300, 400);
1826  auto points = r.GetPoints();
1827  ASSERT_POINT_NEAR(points[0], Point(100, 200));
1828  ASSERT_POINT_NEAR(points[1], Point(400, 200));
1829  ASSERT_POINT_NEAR(points[2], Point(100, 600));
1830  ASSERT_POINT_NEAR(points[3], Point(400, 600));
1831  }
1832 
1833  {
1834  Rect r = Rect::MakeMaximum();
1835  auto points = r.GetPoints();
1836  ASSERT_EQ(points[0], Point(-std::numeric_limits<float>::infinity(),
1837  -std::numeric_limits<float>::infinity()));
1838  ASSERT_EQ(points[1], Point(std::numeric_limits<float>::infinity(),
1839  -std::numeric_limits<float>::infinity()));
1840  ASSERT_EQ(points[2], Point(-std::numeric_limits<float>::infinity(),
1841  std::numeric_limits<float>::infinity()));
1842  ASSERT_EQ(points[3], Point(std::numeric_limits<float>::infinity(),
1843  std::numeric_limits<float>::infinity()));
1844  }
1845 }

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

◆ TEST() [176/299]

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

Definition at line 1905 of file geometry_unittests.cc.

1905  {
1906  {
1907  Rect r = Rect::MakeXYWH(100, 200, 300, 400);
1908  auto actual = r.GetPositive();
1909  ASSERT_RECT_NEAR(r, actual);
1910  }
1911  {
1912  Rect r = Rect::MakeXYWH(100, 200, -100, -100);
1913  auto actual = r.GetPositive();
1914  Rect expected = Rect::MakeXYWH(0, 100, 100, 100);
1915  ASSERT_RECT_NEAR(expected, actual);
1916  }
1917 }

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

◆ TEST() [177/299]

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

Definition at line 1854 of file geometry_unittests.cc.

1854  {
1855  Rect r = Rect::MakeXYWH(100, 200, 300, 400);
1856  auto points = r.GetTransformedPoints(Matrix::MakeTranslation({10, 20}));
1857  ASSERT_POINT_NEAR(points[0], Point(110, 220));
1858  ASSERT_POINT_NEAR(points[1], Point(410, 220));
1859  ASSERT_POINT_NEAR(points[2], Point(110, 620));
1860  ASSERT_POINT_NEAR(points[3], Point(410, 620));
1861 }

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

◆ TEST() [178/299]

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

Definition at line 1555 of file geometry_unittests.cc.

1555  {
1556  {
1557  Rect a = Rect::MakeXYWH(100, 100, 100, 100);
1558  Rect b = Rect::MakeXYWH(0, 0, 0, 0);
1559 
1560  auto u = a.Intersection(b);
1561  ASSERT_FALSE(u.has_value());
1562  }
1563 
1564  {
1565  Rect a = Rect::MakeXYWH(100, 100, 100, 100);
1566  Rect b = Rect::MakeXYWH(10, 10, 0, 0);
1567  auto u = a.Intersection(b);
1568  ASSERT_FALSE(u.has_value());
1569  }
1570 
1571  {
1572  Rect a = Rect::MakeXYWH(0, 0, 100, 100);
1573  Rect b = Rect::MakeXYWH(10, 10, 100, 100);
1574  auto u = a.Intersection(b);
1575  ASSERT_TRUE(u.has_value());
1576  auto expected = Rect::MakeXYWH(10, 10, 90, 90);
1577  ASSERT_RECT_NEAR(u.value(), expected);
1578  }
1579 
1580  {
1581  Rect a = Rect::MakeXYWH(0, 0, 100, 100);
1582  Rect b = Rect::MakeXYWH(100, 100, 100, 100);
1583  auto u = a.Intersection(b);
1584  ASSERT_FALSE(u.has_value());
1585  }
1586 
1587  {
1588  Rect a = Rect::MakeMaximum();
1589  Rect b = Rect::MakeXYWH(10, 10, 300, 300);
1590  auto u = a.Intersection(b);
1591  ASSERT_TRUE(u);
1592  ASSERT_RECT_NEAR(u.value(), b);
1593  }
1594 
1595  {
1596  Rect a = Rect::MakeMaximum();
1597  Rect b = Rect::MakeMaximum();
1598  auto u = a.Intersection(b);
1599  ASSERT_TRUE(u);
1600  ASSERT_EQ(u, Rect::MakeMaximum());
1601  }
1602 }

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

◆ TEST() [179/299]

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

Definition at line 1658 of file geometry_unittests.cc.

1658  {
1659  {
1660  Rect a = Rect::MakeXYWH(100, 100, 100, 100);
1661  Rect b = Rect::MakeXYWH(0, 0, 0, 0);
1662  ASSERT_FALSE(a.IntersectsWithRect(b));
1663  }
1664 
1665  {
1666  Rect a = Rect::MakeXYWH(100, 100, 100, 100);
1667  Rect b = Rect::MakeXYWH(10, 10, 0, 0);
1668  ASSERT_FALSE(a.IntersectsWithRect(b));
1669  }
1670 
1671  {
1672  Rect a = Rect::MakeXYWH(0, 0, 100, 100);
1673  Rect b = Rect::MakeXYWH(10, 10, 100, 100);
1674  ASSERT_TRUE(a.IntersectsWithRect(b));
1675  }
1676 
1677  {
1678  Rect a = Rect::MakeXYWH(0, 0, 100, 100);
1679  Rect b = Rect::MakeXYWH(100, 100, 100, 100);
1680  ASSERT_FALSE(a.IntersectsWithRect(b));
1681  }
1682 
1683  {
1684  Rect a = Rect::MakeMaximum();
1685  Rect b = Rect::MakeXYWH(10, 10, 100, 100);
1686  ASSERT_TRUE(a.IntersectsWithRect(b));
1687  }
1688 
1689  {
1690  Rect a = Rect::MakeMaximum();
1691  Rect b = Rect::MakeMaximum();
1692  ASSERT_TRUE(a.IntersectsWithRect(b));
1693  }
1694 }

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

◆ TEST() [180/299]

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

Definition at line 1863 of file geometry_unittests.cc.

1863  {
1864  {
1865  std::vector<Point> points{{1, 5}, {4, -1}, {0, 6}};
1866  Rect r = Rect::MakePointBounds(points.begin(), points.end()).value();
1867  auto expected = Rect::MakeXYWH(0, -1, 4, 7);
1868  ASSERT_RECT_NEAR(r, expected);
1869  }
1870  {
1871  std::vector<Point> points;
1872  std::optional<Rect> r = Rect::MakePointBounds(points.begin(), points.end());
1873  ASSERT_FALSE(r.has_value());
1874  }
1875 }

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

◆ TEST() [181/299]

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

Definition at line 1960 of file geometry_unittests.cc.

1960  {
1961  {
1962  auto r = Rect::MakeLTRB(-100, -100, 100, 100);
1963  auto actual = r.Project(r);
1964  auto expected = Rect::MakeLTRB(0, 0, 1, 1);
1965  ASSERT_RECT_NEAR(expected, actual);
1966  }
1967  {
1968  auto r = Rect::MakeLTRB(-100, -100, 100, 100);
1969  auto actual = r.Project(Rect::MakeLTRB(0, 0, 100, 100));
1970  auto expected = Rect::MakeLTRB(0.5, 0.5, 1, 1);
1971  ASSERT_RECT_NEAR(expected, actual);
1972  }
1973 }

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

◆ TEST() [182/299]

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

Definition at line 1975 of file geometry_unittests.cc.

1975  {
1976  {
1977  auto r = Rect::MakeLTRB(-100, -100, 100, 100);
1978  ASSERT_EQ(Rect::RoundOut(r), r);
1979  }
1980  {
1981  auto r = Rect::MakeLTRB(-100.1, -100.1, 100.1, 100.1);
1982  ASSERT_EQ(Rect::RoundOut(r), Rect::MakeLTRB(-101, -101, 101, 101));
1983  }
1984 }

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

◆ TEST() [183/299]

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

Definition at line 1919 of file geometry_unittests.cc.

1919  {
1920  {
1921  auto r = Rect::MakeLTRB(-100, -100, 100, 100);
1922  auto actual = r.Scale(0);
1923  auto expected = Rect::MakeLTRB(0, 0, 0, 0);
1924  ASSERT_RECT_NEAR(expected, actual);
1925  }
1926  {
1927  auto r = Rect::MakeLTRB(-100, -100, 100, 100);
1928  auto actual = r.Scale(-2);
1929  auto expected = Rect::MakeLTRB(200, 200, -200, -200);
1930  ASSERT_RECT_NEAR(expected, actual);
1931  }
1932  {
1933  auto r = Rect::MakeLTRB(-100, -100, 100, 100);
1934  auto actual = r.Scale(Point{0, 0});
1935  auto expected = Rect::MakeLTRB(0, 0, 0, 0);
1936  ASSERT_RECT_NEAR(expected, actual);
1937  }
1938  {
1939  auto r = Rect::MakeLTRB(-100, -100, 100, 100);
1940  auto actual = r.Scale(Size{-1, -2});
1941  auto expected = Rect::MakeLTRB(100, 200, -100, -200);
1942  ASSERT_RECT_NEAR(expected, actual);
1943  }
1944 }

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

◆ TEST() [184/299]

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

Definition at line 1847 of file geometry_unittests.cc.

1847  {
1848  auto r = Rect::MakeLTRB(0, 0, 100, 100);
1849 
1850  ASSERT_EQ(r.Shift(Point(10, 5)), Rect::MakeLTRB(10, 5, 110, 105));
1851  ASSERT_EQ(r.Shift(Point(-10, -5)), Rect::MakeLTRB(-10, -5, 90, 95));
1852 }

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

◆ TEST() [185/299]

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

Definition at line 1469 of file geometry_unittests.cc.

1469  {
1470  {
1471  Rect a = Rect::MakeXYWH(100, 100, 100, 100);
1472  Rect b = Rect::MakeXYWH(0, 0, 0, 0);
1473  auto u = a.Union(b);
1474  auto expected = Rect::MakeXYWH(0, 0, 200, 200);
1475  ASSERT_RECT_NEAR(u, expected);
1476  }
1477 
1478  {
1479  Rect a = Rect::MakeXYWH(100, 100, 100, 100);
1480  Rect b = Rect::MakeXYWH(10, 10, 0, 0);
1481  auto u = a.Union(b);
1482  auto expected = Rect::MakeXYWH(10, 10, 190, 190);
1483  ASSERT_RECT_NEAR(u, expected);
1484  }
1485 
1486  {
1487  Rect a = Rect::MakeXYWH(0, 0, 100, 100);
1488  Rect b = Rect::MakeXYWH(10, 10, 100, 100);
1489  auto u = a.Union(b);
1490  auto expected = Rect::MakeXYWH(0, 0, 110, 110);
1491  ASSERT_RECT_NEAR(u, expected);
1492  }
1493 
1494  {
1495  Rect a = Rect::MakeXYWH(0, 0, 100, 100);
1496  Rect b = Rect::MakeXYWH(100, 100, 100, 100);
1497  auto u = a.Union(b);
1498  auto expected = Rect::MakeXYWH(0, 0, 200, 200);
1499  ASSERT_RECT_NEAR(u, expected);
1500  }
1501 }

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

◆ TEST() [186/299]

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

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

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

Definition at line 762 of file geometry_unittests.cc.

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

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

◆ TEST() [189/299]

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

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

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

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

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

Definition at line 2077 of file geometry_unittests.cc.

2077  {
2078  ASSERT_EQ(Color::ToIColor(Color(0, 0, 0, 0)), 0u);
2079  ASSERT_EQ(Color::ToIColor(Color(1.0, 1.0, 1.0, 1.0)), 0xFFFFFFFF);
2080  ASSERT_EQ(Color::ToIColor(Color(0.5, 0.5, 1.0, 1.0)), 0xFF8080FF);
2081 }

References impeller::Color::ToIColor().

◆ TEST() [194/299]

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

Definition at line 1068 of file geometry_unittests.cc.

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

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

◆ TEST() [195/299]

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

Definition at line 1047 of file geometry_unittests.cc.

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

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

◆ TEST() [196/299]

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

Definition at line 1110 of file geometry_unittests.cc.

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

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

◆ TEST() [197/299]

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

Definition at line 1026 of file geometry_unittests.cc.

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

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

◆ TEST() [198/299]

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

Definition at line 1005 of file geometry_unittests.cc.

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

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

◆ TEST() [199/299]

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

Definition at line 2029 of file geometry_unittests.cc.

2029  {
2030  {
2031  std::stringstream stream;
2032  Vector3 m;
2033  stream << m;
2034  ASSERT_EQ(stream.str(), "(0, 0, 0)");
2035  }
2036 
2037  {
2038  std::stringstream stream;
2039  Vector3 m(1, 2, 3);
2040  stream << m;
2041  ASSERT_EQ(stream.str(), "(1, 2, 3)");
2042  }
2043 }

◆ TEST() [200/299]

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

Definition at line 1089 of file geometry_unittests.cc.

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

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

◆ TEST() [201/299]

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

Definition at line 1075 of file geometry_unittests.cc.

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

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

◆ TEST() [202/299]

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

Definition at line 1054 of file geometry_unittests.cc.

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

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

◆ TEST() [203/299]

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

Definition at line 1117 of file geometry_unittests.cc.

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

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

◆ TEST() [204/299]

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

Definition at line 1033 of file geometry_unittests.cc.

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

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

◆ TEST() [205/299]

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

Definition at line 1012 of file geometry_unittests.cc.

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

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

◆ TEST() [206/299]

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

Definition at line 2045 of file geometry_unittests.cc.

2045  {
2046  {
2047  std::stringstream stream;
2048  Vector4 m;
2049  stream << m;
2050  ASSERT_EQ(stream.str(), "(0, 0, 0, 1)");
2051  }
2052 
2053  {
2054  std::stringstream stream;
2055  Vector4 m(1, 2, 3, 4);
2056  stream << m;
2057  ASSERT_EQ(stream.str(), "(1, 2, 3, 4)");
2058  }
2059 }

◆ TEST() [207/299]

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

Definition at line 1096 of file geometry_unittests.cc.

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

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

◆ TEST() [208/299]

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

Definition at line 18 of file host_buffer_unittests.cc.

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

References impeller::HostBuffer::Create().

◆ TEST() [209/299]

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

Definition at line 34 of file host_buffer_unittests.cc.

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

References impeller::HostBuffer::Create().

◆ TEST() [210/299]

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

Definition at line 11 of file host_buffer_unittests.cc.

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

References impeller::HostBuffer::Create().

◆ TEST() [211/299]

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

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

Definition at line 26 of file pass_bindings_cache_unittests.cc.

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

References impeller::PassBindingsCache::BindPipeline().

◆ TEST() [213/299]

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

Definition at line 55 of file pass_bindings_cache_unittests.cc.

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

References impeller::PassBindingsCache::SetScissor().

◆ TEST() [214/299]

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

Definition at line 40 of file pass_bindings_cache_unittests.cc.

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

References impeller::PassBindingsCache::SetStencilReference().

◆ TEST() [215/299]

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

Definition at line 68 of file pass_bindings_cache_unittests.cc.

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

References impeller::PassBindingsCache::SetViewport().

◆ TEST() [216/299]

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

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

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::kAbsGeqTwo);
465  auto path_b = path_a.Clone();
466 
467  EXPECT_EQ(path_a.GetBoundingBox(), path_b.GetBoundingBox());
468  EXPECT_EQ(path_a.GetFillType(), path_b.GetFillType());
469  EXPECT_EQ(path_a.IsConvex(), path_b.IsConvex());
470 
471  auto poly_a = path_a.CreatePolyline(1.0);
472  auto poly_b = path_b.CreatePolyline(1.0);
473 
474  ASSERT_EQ(poly_a.points->size(), poly_b.points->size());
475  ASSERT_EQ(poly_a.contours.size(), poly_b.contours.size());
476 
477  for (auto i = 0u; i < poly_a.points->size(); i++) {
478  EXPECT_EQ((*poly_a.points)[i], (*poly_b.points)[i]);
479  }
480 
481  for (auto i = 0u; i < poly_a.contours.size(); i++) {
482  EXPECT_EQ(poly_a.contours[i].start_index, poly_b.contours[i].start_index);
483  EXPECT_EQ(poly_a.contours[i].start_direction,
484  poly_b.contours[i].start_direction);
485  }
486 }

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

◆ TEST() [219/299]

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

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 impeller::CubicPathComponent::AppendPolylinePoints().

◆ TEST() [221/299]

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::Path::Polyline::contours, impeller::ContourComponent::destination, impeller::Path::Polyline::points, and impeller::PathBuilder::TakePath().

◆ TEST() [222/299]

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

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::Polyline::contours, impeller::Path::CreatePolyline(), impeller::Path::Polyline::GetPoint(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Path::Polyline::points, and impeller::PathBuilder::TakePath().

◆ TEST() [224/299]

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

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

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

◆ TEST() [227/299]

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::Path::Polyline::contours, impeller::LineTo(), impeller::MoveTo(), and impeller::Path::Polyline::points.

◆ TEST() [228/299]

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

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

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::Path::Polyline::contours, impeller::Path::Polyline::GetPoint(), impeller::LineTo(), impeller::PathBuilder::MoveTo(), and impeller::Path::Polyline::points.

◆ TEST() [231/299]

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

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

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(), and impeller::PathBuilder::MoveTo().

◆ TEST() [234/299]

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

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::Path::Polyline::GetContourPointBounds(), impeller::LineTo(), and impeller::MoveTo().

◆ TEST() [236/299]

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

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

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

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

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

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

Definition at line 495 of file rect_unittests.cc.

495  {
496  auto rect1 =
497  Rect::MakeXYWH(472.599945f, 440.999969f, 1102.80005f, 654.000061f);
498  auto rect2 = Rect::MakeXYWH(724.f, 618.f, 600.f, 300.f);
499  EXPECT_TRUE(rect1.Contains(rect2));
500 }

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

◆ TEST() [242/299]

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

Definition at line 434 of file rect_unittests.cc.

434  {
435  EXPECT_EQ(Rect::MakeXYWH(10, 30, 20, 20).GetCenter(), Point(20, 40));
436  EXPECT_EQ(Rect::MakeXYWH(10, 30, 20, 19).GetCenter(), Point(20, 39.5));
437 
438  // Note that we expect a Point as the answer from an IRect
439  EXPECT_EQ(IRect::MakeXYWH(10, 30, 20, 20).GetCenter(), Point(20, 40));
440  EXPECT_EQ(IRect::MakeXYWH(10, 30, 20, 19).GetCenter(), Point(20, 39.5));
441 }

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

◆ TEST() [243/299]

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

Definition at line 222 of file rect_unittests.cc.

222  {
223  EXPECT_EQ(IRect::MakeXYWH(0, 0, 100, 200).Area(), 20000);
224  EXPECT_EQ(IRect::MakeXYWH(10, 20, 100, 200).Area(), 20000);
225  EXPECT_EQ(IRect::MakeXYWH(0, 0, 200, 100).Area(), 20000);
226  EXPECT_EQ(IRect::MakeXYWH(10, 20, 200, 100).Area(), 20000);
227  EXPECT_EQ(IRect::MakeXYWH(0, 0, 100, 100).Area(), 10000);
228  EXPECT_EQ(IRect::MakeXYWH(10, 20, 100, 100).Area(), 10000);
229 }

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

◆ TEST() [244/299]

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

Definition at line 469 of file rect_unittests.cc.

469  {
470  auto rect = IRect::MakeLTRB(100, 100, 200, 200);
471 
472  // Expand(T amount)
473  EXPECT_EQ(rect.Expand(10), IRect::MakeLTRB(90, 90, 210, 210));
474  EXPECT_EQ(rect.Expand(-10), IRect::MakeLTRB(110, 110, 190, 190));
475 
476  // Expand(amount, amount)
477  EXPECT_EQ(rect.Expand(10, 10), IRect::MakeLTRB(90, 90, 210, 210));
478  EXPECT_EQ(rect.Expand(10, -10), IRect::MakeLTRB(90, 110, 210, 190));
479  EXPECT_EQ(rect.Expand(-10, 10), IRect::MakeLTRB(110, 90, 190, 210));
480  EXPECT_EQ(rect.Expand(-10, -10), IRect::MakeLTRB(110, 110, 190, 190));
481 
482  // Expand(IPoint amount)
483  EXPECT_EQ(rect.Expand(IPoint{10, 10}), IRect::MakeLTRB(90, 90, 210, 210));
484  EXPECT_EQ(rect.Expand(IPoint{10, -10}), IRect::MakeLTRB(90, 110, 210, 190));
485  EXPECT_EQ(rect.Expand(IPoint{-10, 10}), IRect::MakeLTRB(110, 90, 190, 210));
486  EXPECT_EQ(rect.Expand(IPoint{-10, -10}), IRect::MakeLTRB(110, 110, 190, 190));
487 
488  // Expand(ISize amount)
489  EXPECT_EQ(rect.Expand(ISize{10, 10}), IRect::MakeLTRB(90, 90, 210, 210));
490  EXPECT_EQ(rect.Expand(ISize{10, -10}), IRect::MakeLTRB(90, 110, 210, 190));
491  EXPECT_EQ(rect.Expand(ISize{-10, 10}), IRect::MakeLTRB(110, 90, 190, 210));
492  EXPECT_EQ(rect.Expand(ISize{-10, -10}), IRect::MakeLTRB(110, 110, 190, 190));
493 }

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

◆ TEST() [245/299]

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

Definition at line 92 of file rect_unittests.cc.

92  {
93  EXPECT_EQ(IRect(IRect::MakeXYWH(2, 3, 7, 15)), //
94  IRect::MakeXYWH(2, 3, 7, 15));
95  EXPECT_EQ(IRect(IRect::MakeLTRB(2, 3, 7, 15)), //
96  IRect::MakeLTRB(2, 3, 7, 15));
97 }

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

◆ TEST() [246/299]

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

Definition at line 80 of file rect_unittests.cc.

80  {
81  EXPECT_EQ(IRect(Rect::MakeXYWH(2, 3, 7, 15)), //
82  IRect::MakeXYWH(2, 3, 7, 15));
83  EXPECT_EQ(IRect(Rect::MakeLTRB(2, 3, 7, 15)), //
84  IRect::MakeLTRB(2, 3, 7, 15));
85 
86  EXPECT_EQ(IRect(Rect::MakeXYWH(2.5, 3.5, 7.75, 15.75)),
87  IRect::MakeXYWH(2, 3, 7, 15));
88  EXPECT_EQ(IRect(Rect::MakeLTRB(2.5, 3.5, 7.75, 15.75)),
89  IRect::MakeLTRB(2, 3, 7, 15));
90 }

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

◆ TEST() [247/299]

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

Definition at line 319 of file rect_unittests.cc.

319  {
320  {
321  // Checks for expected matrix values
322 
323  auto r = IRect::MakeXYWH(100, 200, 200, 400);
324 
325  EXPECT_EQ(r.GetNormalizingTransform(),
326  Matrix::MakeScale({0.005, 0.0025, 1.0}) *
327  Matrix::MakeTranslation({-100, -200}));
328  }
329 
330  {
331  // Checks for expected transform of points relative to the rect
332 
333  auto r = IRect::MakeLTRB(300, 500, 400, 700);
334  auto m = r.GetNormalizingTransform();
335 
336  // The 4 corners of the rect => (0, 0) to (1, 1)
337  EXPECT_EQ(m * Point(300, 500), Point(0, 0));
338  EXPECT_EQ(m * Point(400, 500), Point(1, 0));
339  EXPECT_EQ(m * Point(400, 700), Point(1, 1));
340  EXPECT_EQ(m * Point(300, 700), Point(0, 1));
341 
342  // The center => (0.5, 0.5)
343  EXPECT_EQ(m * Point(350, 600), Point(0.5, 0.5));
344 
345  // Outside the 4 corners => (-1, -1) to (2, 2)
346  EXPECT_EQ(m * Point(200, 300), Point(-1, -1));
347  EXPECT_EQ(m * Point(500, 300), Point(2, -1));
348  EXPECT_EQ(m * Point(500, 900), Point(2, 2));
349  EXPECT_EQ(m * Point(200, 900), Point(-1, 2));
350  }
351 
352  {
353  // Checks for behavior with empty rects
354 
355  auto zero = Matrix::MakeScale({0.0, 0.0, 1.0});
356 
357  // Empty for width and/or height == 0
358  EXPECT_EQ(IRect::MakeXYWH(10, 10, 0, 10).GetNormalizingTransform(), zero);
359  EXPECT_EQ(IRect::MakeXYWH(10, 10, 10, 0).GetNormalizingTransform(), zero);
360  EXPECT_EQ(IRect::MakeXYWH(10, 10, 0, 0).GetNormalizingTransform(), zero);
361 
362  // Empty for width and/or height < 0
363  EXPECT_EQ(IRect::MakeXYWH(10, 10, -1, 10).GetNormalizingTransform(), zero);
364  EXPECT_EQ(IRect::MakeXYWH(10, 10, 10, -1).GetNormalizingTransform(), zero);
365  EXPECT_EQ(IRect::MakeXYWH(10, 10, -1, -1).GetNormalizingTransform(), zero);
366  }
367 }

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

◆ TEST() [248/299]

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

Definition at line 40 of file rect_unittests.cc.

40  {
41  {
42  IRect r = IRect::MakeOriginSize({10, 20}, {50, 40});
43  EXPECT_EQ(r.GetOrigin(), IPoint(10, 20));
44  EXPECT_EQ(r.GetSize(), ISize(50, 40));
45  EXPECT_EQ(r.GetX(), 10);
46  EXPECT_EQ(r.GetY(), 20);
47  EXPECT_EQ(r.GetWidth(), 50);
48  EXPECT_EQ(r.GetHeight(), 40);
49  auto expected_array = std::array<int64_t, 4>{10, 20, 50, 40};
50  EXPECT_EQ(r.GetXYWH(), expected_array);
51  }
52 
53  {
54  IRect r = IRect::MakeLTRB(10, 20, 50, 40);
55  EXPECT_EQ(r.GetOrigin(), IPoint(10, 20));
56  EXPECT_EQ(r.GetSize(), ISize(40, 20));
57  EXPECT_EQ(r.GetX(), 10);
58  EXPECT_EQ(r.GetY(), 20);
59  EXPECT_EQ(r.GetWidth(), 40);
60  EXPECT_EQ(r.GetHeight(), 20);
61  auto expected_array = std::array<int64_t, 4>{10, 20, 40, 20};
62  EXPECT_EQ(r.GetXYWH(), expected_array);
63  }
64 }

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

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

Definition at line 171 of file rect_unittests.cc.

171  {
172  auto test1 = [](IRect rect, int64_t scale) {
173  IRect expected = IRect::MakeXYWH(rect.GetX() * scale, //
174  rect.GetY() * scale, //
175  rect.GetWidth() * scale, //
176  rect.GetHeight() * scale);
177 
178  EXPECT_EQ(rect.Scale(scale), expected) //
179  << rect << " * " << scale;
180  EXPECT_EQ(rect.Scale(scale, scale), expected) //
181  << rect << " * " << scale;
182  EXPECT_EQ(rect.Scale(IPoint(scale, scale)), expected) //
183  << rect << " * " << scale;
184  EXPECT_EQ(rect.Scale(ISize(scale, scale)), expected) //
185  << rect << " * " << scale;
186  };
187 
188  auto test2 = [&test1](IRect rect, int64_t scale_x, int64_t scale_y) {
189  IRect expected = IRect::MakeXYWH(rect.GetX() * scale_x, //
190  rect.GetY() * scale_y, //
191  rect.GetWidth() * scale_x, //
192  rect.GetHeight() * scale_y);
193 
194  EXPECT_EQ(rect.Scale(scale_x, scale_y), expected) //
195  << rect << " * " << scale_x << ", " << scale_y;
196  EXPECT_EQ(rect.Scale(IPoint(scale_x, scale_y)), expected) //
197  << rect << " * " << scale_x << ", " << scale_y;
198  EXPECT_EQ(rect.Scale(ISize(scale_x, scale_y)), expected) //
199  << rect << " * " << scale_x << ", " << scale_y;
200 
201  test1(rect, scale_x);
202  test1(rect, scale_y);
203  };
204 
205  test2(IRect::MakeLTRB(10, 15, 100, 150), 2, 3);
206  test2(IRect::MakeLTRB(10, 15, 100, 150), 3, 2);
207  test2(IRect::MakeLTRB(10, 15, -100, 150), 2, 3);
208  test2(IRect::MakeLTRB(10, 15, 100, -150), 2, 3);
209  test2(IRect::MakeLTRB(10, 15, 100, 150), -2, 3);
210  test2(IRect::MakeLTRB(10, 15, 100, 150), 2, -3);
211 }

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(), and impeller::TRect< T >::Scale().

◆ TEST() [250/299]

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

Definition at line 424 of file rect_unittests.cc.

424  {
425  EXPECT_TRUE(Rect::MakeXYWH(10, 30, 20, 20).IsSquare());
426  EXPECT_FALSE(Rect::MakeXYWH(10, 30, 20, 19).IsSquare());
427  EXPECT_FALSE(Rect::MakeXYWH(10, 30, 19, 20).IsSquare());
428 
429  EXPECT_TRUE(IRect::MakeXYWH(10, 30, 20, 20).IsSquare());
430  EXPECT_FALSE(IRect::MakeXYWH(10, 30, 20, 19).IsSquare());
431  EXPECT_FALSE(IRect::MakeXYWH(10, 30, 19, 20).IsSquare());
432 }

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

◆ TEST() [251/299]

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

Definition at line 410 of file rect_unittests.cc.

410  {
411  Quad quad = {
412  Point(10, 10),
413  Point(20, 10),
414  Point(10, 20),
415  Point(20, 20),
416  };
417  std::optional<Rect> bounds = Rect::MakePointBounds(quad);
418  EXPECT_TRUE(bounds.has_value());
419  if (bounds.has_value()) {
420  EXPECT_TRUE(RectNear(bounds.value(), Rect::MakeLTRB(10, 10, 20, 20)));
421  }
422 }

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

◆ TEST() [252/299]

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

Definition at line 213 of file rect_unittests.cc.

213  {
214  EXPECT_EQ(Rect::MakeXYWH(0, 0, 100, 200).Area(), 20000);
215  EXPECT_EQ(Rect::MakeXYWH(10, 20, 100, 200).Area(), 20000);
216  EXPECT_EQ(Rect::MakeXYWH(0, 0, 200, 100).Area(), 20000);
217  EXPECT_EQ(Rect::MakeXYWH(10, 20, 200, 100).Area(), 20000);
218  EXPECT_EQ(Rect::MakeXYWH(0, 0, 100, 100).Area(), 10000);
219  EXPECT_EQ(Rect::MakeXYWH(10, 20, 100, 100).Area(), 10000);
220 }

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

◆ TEST() [253/299]

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

Definition at line 443 of file rect_unittests.cc.

443  {
444  auto rect = Rect::MakeLTRB(100, 100, 200, 200);
445 
446  // Expand(T amount)
447  EXPECT_EQ(rect.Expand(10), Rect::MakeLTRB(90, 90, 210, 210));
448  EXPECT_EQ(rect.Expand(-10), Rect::MakeLTRB(110, 110, 190, 190));
449 
450  // Expand(amount, amount)
451  EXPECT_EQ(rect.Expand(10, 10), Rect::MakeLTRB(90, 90, 210, 210));
452  EXPECT_EQ(rect.Expand(10, -10), Rect::MakeLTRB(90, 110, 210, 190));
453  EXPECT_EQ(rect.Expand(-10, 10), Rect::MakeLTRB(110, 90, 190, 210));
454  EXPECT_EQ(rect.Expand(-10, -10), Rect::MakeLTRB(110, 110, 190, 190));
455 
456  // Expand(Point amount)
457  EXPECT_EQ(rect.Expand(Point{10, 10}), Rect::MakeLTRB(90, 90, 210, 210));
458  EXPECT_EQ(rect.Expand(Point{10, -10}), Rect::MakeLTRB(90, 110, 210, 190));
459  EXPECT_EQ(rect.Expand(Point{-10, 10}), Rect::MakeLTRB(110, 90, 190, 210));
460  EXPECT_EQ(rect.Expand(Point{-10, -10}), Rect::MakeLTRB(110, 110, 190, 190));
461 
462  // Expand(Size amount)
463  EXPECT_EQ(rect.Expand(Size{10, 10}), Rect::MakeLTRB(90, 90, 210, 210));
464  EXPECT_EQ(rect.Expand(Size{10, -10}), Rect::MakeLTRB(90, 110, 210, 190));
465  EXPECT_EQ(rect.Expand(Size{-10, 10}), Rect::MakeLTRB(110, 90, 190, 210));
466  EXPECT_EQ(rect.Expand(Size{-10, -10}), Rect::MakeLTRB(110, 110, 190, 190));
467 }

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

◆ TEST() [254/299]

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

Definition at line 73 of file rect_unittests.cc.

73  {
74  EXPECT_EQ(Rect(IRect::MakeXYWH(2, 3, 7, 15)),
75  Rect::MakeXYWH(2.0, 3.0, 7.0, 15.0));
76  EXPECT_EQ(Rect(IRect::MakeLTRB(2, 3, 7, 15)),
77  Rect::MakeLTRB(2.0, 3.0, 7.0, 15.0));
78 }

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

◆ TEST() [255/299]

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

Definition at line 66 of file rect_unittests.cc.

66  {
67  EXPECT_EQ(Rect(Rect::MakeXYWH(2, 3, 7, 15)),
68  Rect::MakeXYWH(2.0, 3.0, 7.0, 15.0));
69  EXPECT_EQ(Rect(Rect::MakeLTRB(2, 3, 7, 15)),
70  Rect::MakeLTRB(2.0, 3.0, 7.0, 15.0));
71 }

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

◆ TEST() [256/299]

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

Definition at line 231 of file rect_unittests.cc.

231  {
232  {
233  // Checks for expected matrix values
234 
235  auto r = Rect::MakeXYWH(100, 200, 200, 400);
236 
237  EXPECT_EQ(r.GetNormalizingTransform(),
238  Matrix::MakeScale({0.005, 0.0025, 1.0}) *
239  Matrix::MakeTranslation({-100, -200}));
240  }
241 
242  {
243  // Checks for expected transform of points relative to the rect
244 
245  auto r = Rect::MakeLTRB(300, 500, 400, 700);
246  auto m = r.GetNormalizingTransform();
247 
248  // The 4 corners of the rect => (0, 0) to (1, 1)
249  EXPECT_EQ(m * Point(300, 500), Point(0, 0));
250  EXPECT_EQ(m * Point(400, 500), Point(1, 0));
251  EXPECT_EQ(m * Point(400, 700), Point(1, 1));
252  EXPECT_EQ(m * Point(300, 700), Point(0, 1));
253 
254  // The center => (0.5, 0.5)
255  EXPECT_EQ(m * Point(350, 600), Point(0.5, 0.5));
256 
257  // Outside the 4 corners => (-1, -1) to (2, 2)
258  EXPECT_EQ(m * Point(200, 300), Point(-1, -1));
259  EXPECT_EQ(m * Point(500, 300), Point(2, -1));
260  EXPECT_EQ(m * Point(500, 900), Point(2, 2));
261  EXPECT_EQ(m * Point(200, 900), Point(-1, 2));
262  }
263 
264  {
265  // Checks for behavior with empty rects
266 
267  auto zero = Matrix::MakeScale({0.0, 0.0, 1.0});
268 
269  // Empty for width and/or height == 0
270  EXPECT_EQ(Rect::MakeXYWH(10, 10, 0, 10).GetNormalizingTransform(), zero);
271  EXPECT_EQ(Rect::MakeXYWH(10, 10, 10, 0).GetNormalizingTransform(), zero);
272  EXPECT_EQ(Rect::MakeXYWH(10, 10, 0, 0).GetNormalizingTransform(), zero);
273 
274  // Empty for width and/or height < 0
275  EXPECT_EQ(Rect::MakeXYWH(10, 10, -1, 10).GetNormalizingTransform(), zero);
276  EXPECT_EQ(Rect::MakeXYWH(10, 10, 10, -1).GetNormalizingTransform(), zero);
277  EXPECT_EQ(Rect::MakeXYWH(10, 10, -1, -1).GetNormalizingTransform(), zero);
278  }
279 
280  {
281  // Checks for behavior with non-finite rects
282 
283  auto z = Matrix::MakeScale({0.0, 0.0, 1.0});
284  auto nan = std::numeric_limits<Scalar>::quiet_NaN();
285  auto inf = std::numeric_limits<Scalar>::infinity();
286 
287  // Non-finite for width and/or height == nan
288  EXPECT_EQ(Rect::MakeXYWH(10, 10, nan, 10).GetNormalizingTransform(), z);
289  EXPECT_EQ(Rect::MakeXYWH(10, 10, 10, nan).GetNormalizingTransform(), z);
290  EXPECT_EQ(Rect::MakeXYWH(10, 10, nan, nan).GetNormalizingTransform(), z);
291 
292  // Non-finite for width and/or height == inf
293  EXPECT_EQ(Rect::MakeXYWH(10, 10, inf, 10).GetNormalizingTransform(), z);
294  EXPECT_EQ(Rect::MakeXYWH(10, 10, 10, inf).GetNormalizingTransform(), z);
295  EXPECT_EQ(Rect::MakeXYWH(10, 10, inf, inf).GetNormalizingTransform(), z);
296 
297  // Non-finite for width and/or height == -inf
298  EXPECT_EQ(Rect::MakeXYWH(10, 10, -inf, 10).GetNormalizingTransform(), z);
299  EXPECT_EQ(Rect::MakeXYWH(10, 10, 10, -inf).GetNormalizingTransform(), z);
300  EXPECT_EQ(Rect::MakeXYWH(10, 10, -inf, -inf).GetNormalizingTransform(), z);
301 
302  // Non-finite for origin X and/or Y == nan
303  EXPECT_EQ(Rect::MakeXYWH(nan, 10, 10, 10).GetNormalizingTransform(), z);
304  EXPECT_EQ(Rect::MakeXYWH(10, nan, 10, 10).GetNormalizingTransform(), z);
305  EXPECT_EQ(Rect::MakeXYWH(nan, nan, 10, 10).GetNormalizingTransform(), z);
306 
307  // Non-finite for origin X and/or Y == inf
308  EXPECT_EQ(Rect::MakeXYWH(inf, 10, 10, 10).GetNormalizingTransform(), z);
309  EXPECT_EQ(Rect::MakeXYWH(10, inf, 10, 10).GetNormalizingTransform(), z);
310  EXPECT_EQ(Rect::MakeXYWH(inf, inf, 10, 10).GetNormalizingTransform(), z);
311 
312  // Non-finite for origin X and/or Y == -inf
313  EXPECT_EQ(Rect::MakeXYWH(-inf, 10, 10, 10).GetNormalizingTransform(), z);
314  EXPECT_EQ(Rect::MakeXYWH(10, -inf, 10, 10).GetNormalizingTransform(), z);
315  EXPECT_EQ(Rect::MakeXYWH(-inf, -inf, 10, 10).GetNormalizingTransform(), z);
316  }
317 }

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

◆ TEST() [257/299]

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

Definition at line 99 of file rect_unittests.cc.

99  {
100  {
101  Size s(100, 200);
102  Rect r = Rect::MakeSize(s);
103  Rect expected = Rect::MakeLTRB(0, 0, 100, 200);
104  EXPECT_RECT_NEAR(r, expected);
105  }
106 
107  {
108  ISize s(100, 200);
109  Rect r = Rect::MakeSize(s);
110  Rect expected = Rect::MakeLTRB(0, 0, 100, 200);
111  EXPECT_RECT_NEAR(r, expected);
112  }
113 
114  {
115  Size s(100, 200);
116  IRect r = IRect::MakeSize(s);
117  IRect expected = IRect::MakeLTRB(0, 0, 100, 200);
118  EXPECT_EQ(r, expected);
119  }
120 
121  {
122  ISize s(100, 200);
123  IRect r = IRect::MakeSize(s);
124  IRect expected = IRect::MakeLTRB(0, 0, 100, 200);
125  EXPECT_EQ(r, expected);
126  }
127 }

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

◆ TEST() [258/299]

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

Definition at line 14 of file rect_unittests.cc.

14  {
15  {
16  Rect r = Rect::MakeOriginSize({10, 20}, {50, 40});
17  EXPECT_EQ(r.GetOrigin(), Point(10, 20));
18  EXPECT_EQ(r.GetSize(), Size(50, 40));
19  EXPECT_EQ(r.GetX(), 10);
20  EXPECT_EQ(r.GetY(), 20);
21  EXPECT_EQ(r.GetWidth(), 50);
22  EXPECT_EQ(r.GetHeight(), 40);
23  auto expected_array = std::array<Scalar, 4>{10, 20, 50, 40};
24  EXPECT_EQ(r.GetXYWH(), expected_array);
25  }
26 
27  {
28  Rect r = Rect::MakeLTRB(10, 20, 50, 40);
29  EXPECT_EQ(r.GetOrigin(), Point(10, 20));
30  EXPECT_EQ(r.GetSize(), Size(40, 20));
31  EXPECT_EQ(r.GetX(), 10);
32  EXPECT_EQ(r.GetY(), 20);
33  EXPECT_EQ(r.GetWidth(), 40);
34  EXPECT_EQ(r.GetHeight(), 20);
35  auto expected_array = std::array<Scalar, 4>{10, 20, 40, 20};
36  EXPECT_EQ(r.GetXYWH(), expected_array);
37  }
38 }

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

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

Definition at line 129 of file rect_unittests.cc.

129  {
130  auto test1 = [](Rect rect, Scalar scale) {
131  Rect expected = Rect::MakeXYWH(rect.GetX() * scale, //
132  rect.GetY() * scale, //
133  rect.GetWidth() * scale, //
134  rect.GetHeight() * scale);
135 
136  EXPECT_RECT_NEAR(rect.Scale(scale), expected) //
137  << rect << " * " << scale;
138  EXPECT_RECT_NEAR(rect.Scale(scale, scale), expected) //
139  << rect << " * " << scale;
140  EXPECT_RECT_NEAR(rect.Scale(Point(scale, scale)), expected) //
141  << rect << " * " << scale;
142  EXPECT_RECT_NEAR(rect.Scale(Size(scale, scale)), expected) //
143  << rect << " * " << scale;
144  };
145 
146  auto test2 = [&test1](Rect rect, Scalar scale_x, Scalar scale_y) {
147  Rect expected = Rect::MakeXYWH(rect.GetX() * scale_x, //
148  rect.GetY() * scale_y, //
149  rect.GetWidth() * scale_x, //
150  rect.GetHeight() * scale_y);
151 
152  EXPECT_RECT_NEAR(rect.Scale(scale_x, scale_y), expected) //
153  << rect << " * " << scale_x << ", " << scale_y;
154  EXPECT_RECT_NEAR(rect.Scale(Point(scale_x, scale_y)), expected) //
155  << rect << " * " << scale_x << ", " << scale_y;
156  EXPECT_RECT_NEAR(rect.Scale(Size(scale_x, scale_y)), expected) //
157  << rect << " * " << scale_x << ", " << scale_y;
158 
159  test1(rect, scale_x);
160  test1(rect, scale_y);
161  };
162 
163  test2(Rect::MakeLTRB(10, 15, 100, 150), 2.5, 3.5);
164  test2(Rect::MakeLTRB(10, 15, 100, 150), 3.5, 2.5);
165  test2(Rect::MakeLTRB(10, 15, -100, 150), 2.5, 3.5);
166  test2(Rect::MakeLTRB(10, 15, 100, -150), 2.5, 3.5);
167  test2(Rect::MakeLTRB(10, 15, 100, 150), -2.5, 3.5);
168  test2(Rect::MakeLTRB(10, 15, 100, 150), 2.5, -3.5);
169 }

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(), and impeller::TRect< T >::Scale().

◆ TEST() [260/299]

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

Definition at line 45 of file render_target_cache_unittests.cc.

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

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

◆ TEST() [261/299]

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

Definition at line 73 of file render_target_cache_unittests.cc.

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

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

◆ TEST() [262/299]

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

Definition at line 17 of file resource_manager_vk_unittests.cc.

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

References impeller::ResourceManagerVK::Create().

◆ TEST() [263/299]

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

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

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

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

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

impeller::testing::TEST ( SizeTest  ,
IRectIsEmpty   
)

Definition at line 393 of file rect_unittests.cc.

393  {
394  // Non-empty
395  EXPECT_FALSE(IRect::MakeXYWH(1, 2, 10, 7).IsEmpty());
396 
397  // Empty both width and height both 0 or negative, in all combinations
398  EXPECT_TRUE(IRect::MakeXYWH(1, 2, 0, 0).IsEmpty());
399  EXPECT_TRUE(IRect::MakeXYWH(1, 2, -1, -1).IsEmpty());
400  EXPECT_TRUE(IRect::MakeXYWH(1, 2, -1, 0).IsEmpty());
401  EXPECT_TRUE(IRect::MakeXYWH(1, 2, 0, -1).IsEmpty());
402 
403  // Empty for 0 or negative width or height (but not both at the same time)
404  EXPECT_TRUE(IRect::MakeXYWH(1, 2, 10, 0).IsEmpty());
405  EXPECT_TRUE(IRect::MakeXYWH(1, 2, 10, -1).IsEmpty());
406  EXPECT_TRUE(IRect::MakeXYWH(1, 2, 0, 7).IsEmpty());
407  EXPECT_TRUE(IRect::MakeXYWH(1, 2, -1, 7).IsEmpty());
408 }

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

◆ TEST() [269/299]

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

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

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

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

impeller::testing::TEST ( SizeTest  ,
RectIsEmpty   
)

Definition at line 369 of file rect_unittests.cc.

369  {
370  auto nan = std::numeric_limits<Scalar>::quiet_NaN();
371 
372  // Non-empty
373  EXPECT_FALSE(Rect::MakeXYWH(1.5, 2.3, 10.5, 7.2).IsEmpty());
374 
375  // Empty both width and height both 0 or negative, in all combinations
376  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, 0.0, 0.0).IsEmpty());
377  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, -1.0, -1.0).IsEmpty());
378  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, 0.0, -1.0).IsEmpty());
379  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, -1.0, 0.0).IsEmpty());
380 
381  // Empty for 0 or negative width or height (but not both at the same time)
382  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, 10.5, 0.0).IsEmpty());
383  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, 10.5, -1.0).IsEmpty());
384  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, 0.0, 7.2).IsEmpty());
385  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, -1.0, 7.2).IsEmpty());
386 
387  // Empty for NaN in width or height or both
388  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, 10.5, nan).IsEmpty());
389  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, nan, 7.2).IsEmpty());
390  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, nan, nan).IsEmpty());
391 }

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

◆ TEST() [274/299]

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

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

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

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

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

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

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

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

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

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

Definition at line 72 of file base_unittests.cc.

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

References impeller::SPrintF().

◆ TEST() [284/299]

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

Definition at line 137 of file tessellator_unittests.cc.

137  {
138  auto tessellator = std::make_shared<Tessellator>();
139 
140  auto test = [&tessellator](const Matrix& transform, Scalar radius) {
141  auto generator = tessellator->FilledCircle(transform, {}, radius);
142  size_t quadrant_divisions = generator.GetVertexCount() / 4;
143 
144  // Confirm the approximation error is within the currently accepted
145  // |kCircleTolerance| value advertised by |CircleTessellator|.
146  // (With an additional 1% tolerance for floating point rounding.)
147  double angle = kPiOver2 / quadrant_divisions;
148  Point first = {radius, 0};
149  Point next = {static_cast<Scalar>(cos(angle) * radius),
150  static_cast<Scalar>(sin(angle) * radius)};
151  Point midpoint = (first + next) * 0.5;
152  EXPECT_GE(midpoint.GetLength(),
153  radius - Tessellator::kCircleTolerance * 1.01)
154  << ", transform = " << transform << ", radius = " << radius
155  << ", divisions = " << quadrant_divisions;
156  };
157 
158  test({}, 0.0);
159  test({}, 0.9);
160  test({}, 1.0);
161  test({}, 1.9);
162  test(Matrix::MakeScale(Vector2(2.0, 2.0)), 0.95);
163  test({}, 2.0);
164  test(Matrix::MakeScale(Vector2(2.0, 2.0)), 1.0);
165  test({}, 11.9);
166  test({}, 12.0);
167  test({}, 35.9);
168  for (int i = 36; i < 10000; i += 4) {
169  test({}, i);
170  }
171 }

References impeller::TPoint< T >::GetLength(), impeller::Tessellator::kCircleTolerance, impeller::kPiOver2, and impeller::Matrix::MakeScale().

◆ TEST() [285/299]

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

Definition at line 173 of file tessellator_unittests.cc.

173  {
174  auto tessellator = std::make_shared<Tessellator>();
175 
176  auto test = [&tessellator](const Matrix& transform, const Point& center,
177  Scalar radius) {
178  auto generator = tessellator->FilledCircle(transform, center, radius);
179  EXPECT_EQ(generator.GetTriangleType(), PrimitiveType::kTriangleStrip);
180 
181  auto vertex_count = generator.GetVertexCount();
182  auto vertices = std::vector<Point>();
183  generator.GenerateVertices([&vertices](const Point& p) { //
184  vertices.push_back(p);
185  });
186  EXPECT_EQ(vertices.size(), vertex_count);
187  ASSERT_EQ(vertex_count % 4, 0u);
188 
189  auto quadrant_count = vertex_count / 4;
190  for (size_t i = 0; i < quadrant_count; i++) {
191  double angle = kPiOver2 * i / (quadrant_count - 1);
192  double degrees = angle * 180.0 / kPi;
193  double rsin = sin(angle) * radius;
194  double rcos = cos(angle) * radius;
195  EXPECT_POINT_NEAR(vertices[i * 2],
196  Point(center.x - rcos, center.y + rsin))
197  << "vertex " << i << ", angle = " << degrees << std::endl;
198  EXPECT_POINT_NEAR(vertices[i * 2 + 1],
199  Point(center.x - rcos, center.y - rsin))
200  << "vertex " << i << ", angle = " << degrees << std::endl;
201  EXPECT_POINT_NEAR(vertices[vertex_count - i * 2 - 1],
202  Point(center.x + rcos, center.y - rsin))
203  << "vertex " << i << ", angle = " << degrees << std::endl;
204  EXPECT_POINT_NEAR(vertices[vertex_count - i * 2 - 2],
205  Point(center.x + rcos, center.y + rsin))
206  << "vertex " << i << ", angle = " << degrees << std::endl;
207  }
208  };
209 
210  test({}, {}, 2.0);
211  test({}, {10, 10}, 2.0);
212  test(Matrix::MakeScale({500.0, 500.0, 0.0}), {}, 2.0);
213  test(Matrix::MakeScale({0.002, 0.002, 0.0}), {}, 1000.0);
214 }

References EXPECT_POINT_NEAR, impeller::kPi, impeller::kPiOver2, impeller::kTriangleStrip, and impeller::Matrix::MakeScale().

◆ TEST() [286/299]

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

Definition at line 355 of file tessellator_unittests.cc.

355  {
356  auto tessellator = std::make_shared<Tessellator>();
357 
358  auto test = [&tessellator](const Matrix& transform, const Rect& bounds) {
359  auto center = bounds.GetCenter();
360  auto half_size = bounds.GetSize() * 0.5f;
361 
362  auto generator = tessellator->FilledEllipse(transform, bounds);
363  EXPECT_EQ(generator.GetTriangleType(), PrimitiveType::kTriangleStrip);
364 
365  auto vertex_count = generator.GetVertexCount();
366  auto vertices = std::vector<Point>();
367  generator.GenerateVertices([&vertices](const Point& p) { //
368  vertices.push_back(p);
369  });
370  EXPECT_EQ(vertices.size(), vertex_count);
371  ASSERT_EQ(vertex_count % 4, 0u);
372 
373  auto quadrant_count = vertex_count / 4;
374  for (size_t i = 0; i < quadrant_count; i++) {
375  double angle = kPiOver2 * i / (quadrant_count - 1);
376  double degrees = angle * 180.0 / kPi;
377  double rcos = cos(angle) * half_size.width;
378  double rsin = sin(angle) * half_size.height;
379  EXPECT_POINT_NEAR(vertices[i * 2],
380  Point(center.x - rcos, center.y + rsin))
381  << "vertex " << i << ", angle = " << degrees << ", " //
382  << "bounds = " << bounds << std::endl;
383  EXPECT_POINT_NEAR(vertices[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 - 1],
388  Point(center.x + rcos, center.y - rsin))
389  << "vertex " << i << ", angle = " << degrees << ", " //
390  << "bounds = " << bounds << std::endl;
391  EXPECT_POINT_NEAR(vertices[vertex_count - i * 2 - 2],
392  Point(center.x + rcos, center.y + rsin))
393  << "vertex " << i << ", angle = " << degrees << ", " //
394  << "bounds = " << bounds << std::endl;
395  }
396  };
397 
398  // Square bounds should actually use the circle generator, but its
399  // results should match the same math as the ellipse generator.
400  test({}, Rect::MakeXYWH(0, 0, 2, 2));
401 
402  test({}, Rect::MakeXYWH(0, 0, 2, 3));
403  test({}, Rect::MakeXYWH(0, 0, 3, 2));
404  test({}, Rect::MakeXYWH(5, 10, 2, 3));
405  test({}, Rect::MakeXYWH(16, 7, 3, 2));
406  test(Matrix::MakeScale({500.0, 500.0, 0.0}), Rect::MakeXYWH(5, 10, 3, 2));
407  test(Matrix::MakeScale({500.0, 500.0, 0.0}), Rect::MakeXYWH(5, 10, 2, 3));
408  test(Matrix::MakeScale({0.002, 0.002, 0.0}),
409  Rect::MakeXYWH(5000, 10000, 3000, 2000));
410  test(Matrix::MakeScale({0.002, 0.002, 0.0}),
411  Rect::MakeXYWH(5000, 10000, 2000, 3000));
412 }

References EXPECT_POINT_NEAR, impeller::kPi, impeller::kPiOver2, impeller::kTriangleStrip, impeller::Matrix::MakeScale(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [287/299]

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

Definition at line 414 of file tessellator_unittests.cc.

414  {
415  auto tessellator = std::make_shared<Tessellator>();
416 
417  auto test = [&tessellator](const Matrix& transform, const Rect& bounds,
418  const Size& radii) {
419  FML_DCHECK(radii.width * 2 <= bounds.GetWidth()) << radii << bounds;
420  FML_DCHECK(radii.height * 2 <= bounds.GetHeight()) << radii << bounds;
421 
422  Scalar middle_left = bounds.GetX() + radii.width;
423  Scalar middle_top = bounds.GetY() + radii.height;
424  Scalar middle_right = bounds.GetX() + bounds.GetWidth() - radii.width;
425  Scalar middle_bottom = bounds.GetY() + bounds.GetHeight() - radii.height;
426 
427  auto generator = tessellator->FilledRoundRect(transform, bounds, radii);
428  EXPECT_EQ(generator.GetTriangleType(), PrimitiveType::kTriangleStrip);
429 
430  auto vertex_count = generator.GetVertexCount();
431  auto vertices = std::vector<Point>();
432  generator.GenerateVertices([&vertices](const Point& p) { //
433  vertices.push_back(p);
434  });
435  EXPECT_EQ(vertices.size(), vertex_count);
436  ASSERT_EQ(vertex_count % 4, 0u);
437 
438  auto quadrant_count = vertex_count / 4;
439  for (size_t i = 0; i < quadrant_count; i++) {
440  double angle = kPiOver2 * i / (quadrant_count - 1);
441  double degrees = angle * 180.0 / kPi;
442  double rcos = cos(angle) * radii.width;
443  double rsin = sin(angle) * radii.height;
444  EXPECT_POINT_NEAR(vertices[i * 2],
445  Point(middle_left - rcos, middle_bottom + rsin))
446  << "vertex " << i << ", angle = " << degrees << ", " //
447  << "bounds = " << bounds << std::endl;
448  EXPECT_POINT_NEAR(vertices[i * 2 + 1],
449  Point(middle_left - rcos, middle_top - rsin))
450  << "vertex " << i << ", angle = " << degrees << ", " //
451  << "bounds = " << bounds << std::endl;
452  EXPECT_POINT_NEAR(vertices[vertex_count - i * 2 - 1],
453  Point(middle_right + rcos, middle_top - rsin))
454  << "vertex " << i << ", angle = " << degrees << ", " //
455  << "bounds = " << bounds << std::endl;
456  EXPECT_POINT_NEAR(vertices[vertex_count - i * 2 - 2],
457  Point(middle_right + rcos, middle_bottom + rsin))
458  << "vertex " << i << ", angle = " << degrees << ", " //
459  << "bounds = " << bounds << std::endl;
460  }
461  };
462 
463  // Both radii spanning the bounds should actually use the circle/ellipse
464  // generator, but their results should match the same math as the round
465  // rect generator.
466  test({}, Rect::MakeXYWH(0, 0, 20, 20), {10, 10});
467 
468  // One radius spanning the bounds, but not the other will not match the
469  // round rect math if the generator transfers to circle/ellipse
470  test({}, Rect::MakeXYWH(0, 0, 20, 20), {10, 5});
471  test({}, Rect::MakeXYWH(0, 0, 20, 20), {5, 10});
472 
473  test({}, Rect::MakeXYWH(0, 0, 20, 30), {2, 2});
474  test({}, Rect::MakeXYWH(0, 0, 30, 20), {2, 2});
475  test({}, Rect::MakeXYWH(5, 10, 20, 30), {2, 3});
476  test({}, Rect::MakeXYWH(16, 7, 30, 20), {2, 3});
477  test(Matrix::MakeScale({500.0, 500.0, 0.0}), Rect::MakeXYWH(5, 10, 30, 20),
478  {2, 3});
479  test(Matrix::MakeScale({500.0, 500.0, 0.0}), Rect::MakeXYWH(5, 10, 20, 30),
480  {2, 3});
481  test(Matrix::MakeScale({0.002, 0.002, 0.0}),
482  Rect::MakeXYWH(5000, 10000, 3000, 2000), {50, 70});
483  test(Matrix::MakeScale({0.002, 0.002, 0.0}),
484  Rect::MakeXYWH(5000, 10000, 2000, 3000), {50, 70});
485 }

References EXPECT_POINT_NEAR, impeller::kPi, impeller::kPiOver2, impeller::kTriangleStrip, impeller::Matrix::MakeScale(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [288/299]

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

Definition at line 284 of file tessellator_unittests.cc.

284  {
285  auto tessellator = std::make_shared<Tessellator>();
286 
287  auto test = [&tessellator](const Matrix& transform, const Point& p0,
288  const Point& p1, Scalar radius) {
289  auto generator = tessellator->RoundCapLine(transform, p0, p1, radius);
290  EXPECT_EQ(generator.GetTriangleType(), PrimitiveType::kTriangleStrip);
291 
292  auto vertex_count = generator.GetVertexCount();
293  auto vertices = std::vector<Point>();
294  generator.GenerateVertices([&vertices](const Point& p) { //
295  vertices.push_back(p);
296  });
297  EXPECT_EQ(vertices.size(), vertex_count);
298  ASSERT_EQ(vertex_count % 4, 0u);
299 
300  Point along = p1 - p0;
301  Scalar length = along.GetLength();
302  if (length > 0) {
303  along *= radius / length;
304  } else {
305  along = {radius, 0};
306  }
307  Point across = {-along.y, along.x};
308 
309  auto quadrant_count = vertex_count / 4;
310  for (size_t i = 0; i < quadrant_count; i++) {
311  double angle = kPiOver2 * i / (quadrant_count - 1);
312  double degrees = angle * 180.0 / kPi;
313  Point relative_along = along * cos(angle);
314  Point relative_across = across * sin(angle);
315  EXPECT_POINT_NEAR(vertices[i * 2], //
316  p0 - relative_along + relative_across)
317  << "vertex " << i << ", angle = " << degrees << ", " //
318  << "line = " << p0 << " => " << p1 << ", " //
319  << "radius = " << radius << std::endl;
320  EXPECT_POINT_NEAR(vertices[i * 2 + 1], //
321  p0 - relative_along - relative_across)
322  << "vertex " << i << ", angle = " << degrees << ", " //
323  << "line = " << p0 << " => " << p1 << ", " //
324  << "radius = " << radius << std::endl;
325  EXPECT_POINT_NEAR(vertices[vertex_count - i * 2 - 1], //
326  p1 + relative_along - relative_across)
327  << "vertex " << i << ", angle = " << degrees << ", " //
328  << "line = " << p0 << " => " << p1 << ", " //
329  << "radius = " << radius << std::endl;
330  EXPECT_POINT_NEAR(vertices[vertex_count - i * 2 - 2], //
331  p1 + relative_along + relative_across)
332  << "vertex " << i << ", angle = " << degrees << ", " //
333  << "line = " << p0 << " => " << p1 << ", " //
334  << "radius = " << radius << std::endl;
335  }
336  };
337 
338  // Empty line should actually use the circle generator, but its
339  // results should match the same math as the round cap generator.
340  test({}, {0, 0}, {0, 0}, 10);
341 
342  test({}, {0, 0}, {10, 0}, 2);
343  test({}, {10, 0}, {0, 0}, 2);
344  test({}, {0, 0}, {10, 10}, 2);
345 
346  test(Matrix::MakeScale({500.0, 500.0, 0.0}), {0, 0}, {10, 0}, 2);
347  test(Matrix::MakeScale({500.0, 500.0, 0.0}), {10, 0}, {0, 0}, 2);
348  test(Matrix::MakeScale({500.0, 500.0, 0.0}), {0, 0}, {10, 10}, 2);
349 
350  test(Matrix::MakeScale({0.002, 0.002, 0.0}), {0, 0}, {10, 0}, 2);
351  test(Matrix::MakeScale({0.002, 0.002, 0.0}), {10, 0}, {0, 0}, 2);
352  test(Matrix::MakeScale({0.002, 0.002, 0.0}), {0, 0}, {10, 10}, 2);
353 }

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

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

Definition at line 216 of file tessellator_unittests.cc.

216  {
217  auto tessellator = std::make_shared<Tessellator>();
218 
219  auto test = [&tessellator](const Matrix& transform, const Point& center,
220  Scalar radius, Scalar half_width) {
221  ASSERT_GT(radius, half_width);
222  auto generator =
223  tessellator->StrokedCircle(transform, center, radius, half_width);
224  EXPECT_EQ(generator.GetTriangleType(), PrimitiveType::kTriangleStrip);
225 
226  auto vertex_count = generator.GetVertexCount();
227  auto vertices = std::vector<Point>();
228  generator.GenerateVertices([&vertices](const Point& p) { //
229  vertices.push_back(p);
230  });
231  EXPECT_EQ(vertices.size(), vertex_count);
232  ASSERT_EQ(vertex_count % 4, 0u);
233 
234  auto quadrant_count = vertex_count / 8;
235 
236  // Test outer points first
237  for (size_t i = 0; i < quadrant_count; i++) {
238  double angle = kPiOver2 * i / (quadrant_count - 1);
239  double degrees = angle * 180.0 / kPi;
240  double rsin = sin(angle) * (radius + half_width);
241  double rcos = cos(angle) * (radius + half_width);
242  EXPECT_POINT_NEAR(vertices[i * 2],
243  Point(center.x - rcos, center.y - rsin))
244  << "vertex " << i << ", angle = " << degrees << std::endl;
245  EXPECT_POINT_NEAR(vertices[quadrant_count * 2 + i * 2],
246  Point(center.x + rsin, center.y - rcos))
247  << "vertex " << i << ", angle = " << degrees << std::endl;
248  EXPECT_POINT_NEAR(vertices[quadrant_count * 4 + i * 2],
249  Point(center.x + rcos, center.y + rsin))
250  << "vertex " << i << ", angle = " << degrees << std::endl;
251  EXPECT_POINT_NEAR(vertices[quadrant_count * 6 + i * 2],
252  Point(center.x - rsin, center.y + rcos))
253  << "vertex " << i << ", angle = " << degrees << std::endl;
254  }
255 
256  // Then test innerer points
257  for (size_t i = 0; i < quadrant_count; i++) {
258  double angle = kPiOver2 * i / (quadrant_count - 1);
259  double degrees = angle * 180.0 / kPi;
260  double rsin = sin(angle) * (radius - half_width);
261  double rcos = cos(angle) * (radius - half_width);
262  EXPECT_POINT_NEAR(vertices[i * 2 + 1],
263  Point(center.x - rcos, center.y - rsin))
264  << "vertex " << i << ", angle = " << degrees << std::endl;
265  EXPECT_POINT_NEAR(vertices[quadrant_count * 2 + i * 2 + 1],
266  Point(center.x + rsin, center.y - rcos))
267  << "vertex " << i << ", angle = " << degrees << std::endl;
268  EXPECT_POINT_NEAR(vertices[quadrant_count * 4 + i * 2 + 1],
269  Point(center.x + rcos, center.y + rsin))
270  << "vertex " << i << ", angle = " << degrees << std::endl;
271  EXPECT_POINT_NEAR(vertices[quadrant_count * 6 + i * 2 + 1],
272  Point(center.x - rsin, center.y + rcos))
273  << "vertex " << i << ", angle = " << degrees << std::endl;
274  }
275  };
276 
277  test({}, {}, 2.0, 1.0);
278  test({}, {}, 2.0, 0.5);
279  test({}, {10, 10}, 2.0, 1.0);
280  test(Matrix::MakeScale({500.0, 500.0, 0.0}), {}, 2.0, 1.0);
281  test(Matrix::MakeScale({0.002, 0.002, 0.0}), {}, 1000.0, 10.0);
282 }

References EXPECT_POINT_NEAR, impeller::kPi, impeller::kPiOver2, impeller::kTriangleStrip, and impeller::Matrix::MakeScale().

◆ TEST() [290/299]

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

Definition at line 109 of file tessellator_unittests.cc.

109  {
110  {
111  Tessellator t;
112  // Sanity check simple rectangle.
113  auto pts = t.TessellateConvex(
114  PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 10, 10)).TakePath(), 1.0);
115 
116  std::vector<Point> expected = {
117  {0, 0}, {10, 0}, {0, 10}, {10, 10}, //
118  };
119  EXPECT_EQ(pts, expected);
120  }
121 
122  {
123  Tessellator t;
124  auto pts = t.TessellateConvex(PathBuilder{}
125  .AddRect(Rect::MakeLTRB(0, 0, 10, 10))
126  .AddRect(Rect::MakeLTRB(20, 20, 30, 30))
127  .TakePath(),
128  1.0);
129 
130  std::vector<Point> expected = {{0, 0}, {10, 0}, {0, 10}, {10, 10},
131  {10, 10}, {20, 20}, {20, 20}, {30, 20},
132  {20, 30}, {30, 30}};
133  EXPECT_EQ(pts, expected);
134  }
135 }

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

◆ TEST() [291/299]

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::kPositive);
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::kPositive);
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 =
45  PathBuilder{}.AddLine({0, 0}, {0, 1}).TakePath(FillType::kPositive);
46  Tessellator::Result result = t.Tessellate(
47  path, 1.0f,
48  [](const float* vertices, size_t vertices_count,
49  const uint16_t* indices, size_t indices_count) { return true; });
50 
51  ASSERT_EQ(result, Tessellator::Result::kSuccess);
52  }
53 
54  // Many points.
55  {
56  Tessellator t;
57  PathBuilder builder;
58  for (int i = 0; i < 1000; i++) {
59  auto coord = i * 1.0f;
60  builder.AddLine({coord, coord}, {coord + 1, coord + 1});
61  }
62  auto path = builder.TakePath(FillType::kPositive);
63  Tessellator::Result result = t.Tessellate(
64  path, 1.0f,
65  [](const float* vertices, size_t vertices_count,
66  const uint16_t* indices, size_t indices_count) { return true; });
67 
68  ASSERT_EQ(result, Tessellator::Result::kSuccess);
69  }
70 
71  // Closure fails.
72  {
73  Tessellator t;
74  auto path =
75  PathBuilder{}.AddLine({0, 0}, {0, 1}).TakePath(FillType::kPositive);
76  Tessellator::Result result = t.Tessellate(
77  path, 1.0f,
78  [](const float* vertices, size_t vertices_count,
79  const uint16_t* indices, size_t indices_count) { return false; });
80 
81  ASSERT_EQ(result, Tessellator::Result::kInputError);
82  }
83 
84  // More than uint16 points, odd fill mode.
85  {
86  Tessellator t;
87  PathBuilder builder = {};
88  for (auto i = 0; i < 1000; i++) {
89  builder.AddCircle(Point(i, i), 4);
90  }
91  auto path = builder.TakePath(FillType::kOdd);
92  bool no_indices = false;
93  size_t count = 0u;
94  Tessellator::Result result = t.Tessellate(
95  path, 1.0f,
96  [&no_indices, &count](const float* vertices, size_t vertices_count,
97  const uint16_t* indices, size_t indices_count) {
98  no_indices = indices == nullptr;
99  count = vertices_count;
100  return true;
101  });
102 
103  ASSERT_TRUE(no_indices);
104  ASSERT_TRUE(count >= USHRT_MAX);
105  ASSERT_EQ(result, Tessellator::Result::kSuccess);
106  }
107 }

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

◆ TEST() [292/299]

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

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

Definition at line 22 of file base_unittests.cc.

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

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

◆ TEST() [294/299]

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

Definition at line 31 of file base_unittests.cc.

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

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

◆ TEST() [295/299]

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

Definition at line 39 of file base_unittests.cc.

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

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

◆ TEST() [296/299]

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

Definition at line 53 of file base_unittests.cc.

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

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

◆ TEST() [297/299]

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

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

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

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

Definition at line 122 of file archivist_unittests.cc.

122  {
123  Archive archive(GetArchiveFileName().c_str());
124  ASSERT_TRUE(archive.IsValid());
125  Sample sample;
126  ASSERT_TRUE(archive.Write(sample));
127 }

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

◆ TEST_F() [2/8]

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

Definition at line 129 of file archivist_unittests.cc.

129  {
130  Archive archive(GetArchiveFileName().c_str());
131  ASSERT_TRUE(archive.IsValid());
132 
133  for (size_t i = 0; i < 100; i++) {
134  Sample sample(i + 1);
135  ASSERT_TRUE(archive.Write(sample));
136  }
137 }

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

◆ TEST_F() [3/8]

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

Definition at line 117 of file archivist_unittests.cc.

117  {
118  Archive archive(GetArchiveFileName().c_str());
119  ASSERT_TRUE(archive.IsValid());
120 }

References impeller::Archive::IsValid().

◆ TEST_F() [4/8]

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

Definition at line 189 of file archivist_unittests.cc.

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

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

◆ TEST_F() [5/8]

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

Definition at line 139 of file archivist_unittests.cc.

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

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

◆ TEST_F() [6/8]

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

Definition at line 162 of file archivist_unittests.cc.

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

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

◆ TEST_F() [7/8]

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

Definition at line 112 of file archivist_unittests.cc.

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

References impeller::Archive::IsValid().

◆ TEST_F() [8/8]

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

Definition at line 71 of file golden_tests.cc.

71  {
72  Canvas canvas;
73  Paint paint;
74 
75  paint.color_source = ColorSource::MakeConicalGradient(
76  {125, 125}, 125, {Color(1.0, 0.0, 0.0, 1.0), Color(0.0, 0.0, 1.0, 1.0)},
77  {0, 1}, {180, 180}, 0, Entity::TileMode::kClamp, {});
78 
79  paint.stroke_width = 0.0;
80  paint.style = Paint::Style::kFill;
81  canvas.DrawRect(Rect::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::TRect< Scalar >::MakeXYWH(), impeller::Paint::stroke_width, and impeller::Paint::style.

◆ TEST_P() [1/384]

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

Definition at line 359 of file aiks_path_unittests.cc.

359  {
360  Canvas canvas;
361  canvas.Scale(GetContentScale());
362 
363  Paint paint;
364  paint.color = Color::Red();
365  std::vector<Color> colors = {Color{1.0, 0.0, 0.0, 1.0},
366  Color{0.0, 0.0, 0.0, 1.0}};
367  std::vector<Scalar> stops = {0.0, 1.0};
368  paint.color_source = ColorSource::MakeSweepGradient(
369  {100, 100}, Degrees(45), Degrees(135), std::move(colors),
370  std::move(stops), Entity::TileMode::kMirror, {});
371  paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
372  .style = FilterContents::BlurStyle::kNormal,
373  .sigma = Sigma(20),
374  };
375 
376  PathBuilder builder;
377  builder.AddArc(Rect::MakeXYWH(10, 10, 100, 100), Degrees(0), Degrees(0),
378  false);
379  canvas.DrawPath(builder.TakePath(), paint);
380 
381  // Check that this empty picture can be created without crashing.
382  canvas.EndRecordingAsPicture();
383 }

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

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

Definition at line 490 of file aiks_unittests.cc.

490  {
491  Canvas canvas;
492  Paint paint;
493 
494  paint.color = Color::Red();
495  canvas.DrawPaint(paint);
496 
497  paint.blend_mode = BlendMode::kSourceOver;
498  canvas.SaveLayer(paint);
499 
500  paint.color = Color::White();
501  canvas.DrawRect(Rect::MakeXYWH(100, 100, 400, 400), paint);
502 
503  paint.blend_mode = BlendMode::kSource;
504  canvas.SaveLayer(paint);
505 
506  paint.color = Color::Blue();
507  canvas.DrawRect(Rect::MakeXYWH(200, 200, 200, 200), paint);
508 
509  canvas.Restore();
510  canvas.Restore();
511 
512  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
513 }

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

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

Definition at line 3458 of file aiks_unittests.cc.

3458  {
3459  Canvas canvas;
3460  canvas.Scale(GetContentScale());
3461  canvas.DrawPaint({});
3462  Paint blur = {
3463  .color = Color::Green(),
3464  .mask_blur_descriptor =
3465  Paint::MaskBlurDescriptor{
3466  .style = FilterContents::BlurStyle::kNormal,
3467  .sigma = Sigma(47.6),
3468  },
3469  };
3470  canvas.DrawRect(Rect::MakeXYWH(300, 300, 200, 200), blur);
3471  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3472 }

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

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

Definition at line 3495 of file aiks_unittests.cc.

3495  {
3496  Canvas canvas;
3497  canvas.Scale(GetContentScale());
3498 
3499  auto paint_lines = [&canvas](Scalar dx, Scalar dy, Paint paint) {
3500  auto draw_line = [&canvas, &paint](Point a, Point b) {
3501  canvas.DrawPath(PathBuilder{}.AddLine(a, b).TakePath(), paint);
3502  };
3503  paint.stroke_width = 5;
3504  paint.style = Paint::Style::kStroke;
3505  draw_line(Point(dx + 100, dy + 100), Point(dx + 200, dy + 200));
3506  draw_line(Point(dx + 100, dy + 200), Point(dx + 200, dy + 100));
3507  draw_line(Point(dx + 150, dy + 100), Point(dx + 200, dy + 150));
3508  draw_line(Point(dx + 100, dy + 150), Point(dx + 150, dy + 200));
3509  };
3510 
3511  AiksContext renderer(GetContext(), nullptr);
3512  Canvas recorder_canvas;
3513  for (int x = 0; x < 5; ++x) {
3514  for (int y = 0; y < 5; ++y) {
3515  Rect rect = Rect::MakeXYWH(x * 20, y * 20, 20, 20);
3516  Paint paint{.color =
3517  ((x + y) & 1) == 0 ? Color::Yellow() : Color::Blue()};
3518  recorder_canvas.DrawRect(rect, paint);
3519  }
3520  }
3521  Picture picture = recorder_canvas.EndRecordingAsPicture();
3522  std::shared_ptr<Texture> texture =
3523  picture.ToImage(renderer, ISize{100, 100})->GetTexture();
3524 
3525  ColorSource image_source = ColorSource::MakeImage(
3526  texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {}, {});
3527  std::shared_ptr<ImageFilter> blur_filter = ImageFilter::MakeBlur(
3528  Sigma(5), Sigma(5), FilterContents::BlurStyle::kNormal,
3529  Entity::TileMode::kDecal);
3530  canvas.DrawRect(Rect::MakeLTRB(0, 0, 300, 600),
3531  Paint{.color = Color::DarkGreen()});
3532  canvas.DrawRect(Rect::MakeLTRB(100, 100, 200, 200),
3533  Paint{.color_source = image_source});
3534  canvas.DrawRect(Rect::MakeLTRB(300, 0, 600, 600),
3535  Paint{.color = Color::Red()});
3536  canvas.DrawRect(
3537  Rect::MakeLTRB(400, 100, 500, 200),
3538  Paint{.color_source = image_source, .image_filter = blur_filter});
3539  paint_lines(0, 300, Paint{.color_source = image_source});
3540  paint_lines(300, 300,
3541  Paint{.color_source = image_source, .image_filter = blur_filter});
3542  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3543 }

References impeller::PathBuilder::AddLine(), 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::Paint::stroke_width, impeller::Paint::style, impeller::PathBuilder::TakePath(), impeller::Picture::ToImage(), and impeller::Color::Yellow().

◆ TEST_P() [5/384]

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

Definition at line 2996 of file aiks_unittests.cc.

2996  {
2997  Canvas subcanvas;
2998  subcanvas.DrawRect(Rect::MakeLTRB(-100, -50, 100, 50),
2999  {.color = Color::CornflowerBlue()});
3000  auto picture = subcanvas.EndRecordingAsPicture();
3001 
3002  Canvas canvas;
3003  canvas.Translate({200, 200});
3004  canvas.Rotate(Radians(kPi / 4));
3005  canvas.DrawPicture(picture);
3006 
3007  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3008 }

References impeller::Color::CornflowerBlue(), impeller::Canvas::DrawPicture(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::kPi, impeller::TRect< Scalar >::MakeLTRB(), impeller::Canvas::Rotate(), and impeller::Canvas::Translate().

◆ TEST_P() [6/384]

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

Definition at line 3010 of file aiks_unittests.cc.

3010  {
3011  Canvas subcanvas;
3012  subcanvas.DrawRect(
3013  Rect::MakeLTRB(-100, -50, 100, 50),
3014  {.color = Color::CornflowerBlue(), .blend_mode = BlendMode::kColorDodge});
3015  auto picture = subcanvas.EndRecordingAsPicture();
3016 
3017  Canvas canvas;
3018  canvas.DrawPaint({.color = Color::Black()});
3019  canvas.DrawCircle(Point::MakeXY(150, 150), 25, {.color = Color::Red()});
3020  canvas.DrawPicture(picture);
3021 
3022  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3023 }

References impeller::Color::Black(), impeller::Color::CornflowerBlue(), impeller::Canvas::DrawCircle(), impeller::Canvas::DrawPaint(), impeller::Canvas::DrawPicture(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::kColorDodge, impeller::TRect< Scalar >::MakeLTRB(), impeller::TPoint< Scalar >::MakeXY(), and impeller::Color::Red().

◆ TEST_P() [7/384]

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

Definition at line 3025 of file aiks_unittests.cc.

3025  {
3026  Canvas subcanvas;
3027  subcanvas.SaveLayer({}, {},
3028  ImageFilter::MakeBlur(Sigma(20.0), Sigma(20.0),
3029  FilterContents::BlurStyle::kNormal,
3030  Entity::TileMode::kDecal));
3031  auto image = std::make_shared<Image>(CreateTextureForFixture("kalimba.jpg"));
3032  Paint paint;
3033  paint.color = Color::Red().WithAlpha(0.5);
3034  subcanvas.DrawImage(image, Point::MakeXY(100.0, 100.0), paint);
3035 
3036  auto picture = subcanvas.EndRecordingAsPicture();
3037 
3038  Canvas canvas;
3039  canvas.DrawPaint({.color = Color::Black()});
3040  canvas.DrawCircle(Point::MakeXY(150, 150), 25, {.color = Color::Red()});
3041  canvas.DrawPicture(picture);
3042 
3043  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3044 }

References impeller::Color::Black(), impeller::Paint::color, impeller::Canvas::DrawCircle(), impeller::Canvas::DrawImage(), impeller::Canvas::DrawPaint(), impeller::Canvas::DrawPicture(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kDecal, impeller::FilterContents::kNormal, impeller::ImageFilter::MakeBlur(), impeller::TPoint< Scalar >::MakeXY(), impeller::Color::Red(), impeller::Canvas::SaveLayer(), and impeller::Color::WithAlpha().

◆ TEST_P() [8/384]

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

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

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

Definition at line 339 of file aiks_path_unittests.cc.

339  {
340  PathBuilder builder = {};
341  for (auto i = 0; i < 10; i++) {
342  if (i % 2 == 0) {
343  builder.AddCircle(Point(100 + 50 * i, 100 + 50 * i), 100);
344  } else {
345  builder.MoveTo({100.f + 50.f * i - 100, 100.f + 50.f * i});
346  builder.LineTo({100.f + 50.f * i, 100.f + 50.f * i - 100});
347  builder.LineTo({100.f + 50.f * i - 100, 100.f + 50.f * i - 100});
348  builder.Close();
349  }
350  }
351  builder.SetConvexity(Convexity::kConvex);
352 
353  Canvas canvas;
354  canvas.DrawPath(builder.TakePath(), {.color = Color::Red().WithAlpha(0.4)});
355 
356  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
357 }

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

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

Definition at line 939 of file aiks_unittests.cc.

939  {
940  Canvas canvas;
941  canvas.Scale(Vector2(0.2, 0.2));
942  canvas.DrawPaint({.color = Color::MediumTurquoise()});
943  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
944 }

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

◆ TEST_P() [12/384]

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

Definition at line 946 of file aiks_unittests.cc.

946  {
947  Canvas canvas;
948  canvas.Scale(Vector2(0.2, 0.2));
949  canvas.DrawPaint({.color = Color::MediumTurquoise()});
950  canvas.DrawPaint({.color = Color::Color::OrangeRed().WithAlpha(0.5)});
951  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
952 }

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

◆ TEST_P() [13/384]

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

Definition at line 1024 of file aiks_unittests.cc.

1024  {
1025  auto modes = GetBlendModeSelection();
1026 
1027  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
1028  static Color background = Color::MediumTurquoise();
1029  static Color foreground = Color::Color::OrangeRed().WithAlpha(0.5);
1030  static int current_blend_index = 3;
1031 
1032  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1033  {
1034  ImGui::ColorEdit4("Background", reinterpret_cast<float*>(&background));
1035  ImGui::ColorEdit4("Foreground", reinterpret_cast<float*>(&foreground));
1036  ImGui::ListBox("Blend mode", &current_blend_index,
1037  modes.blend_mode_names.data(),
1038  modes.blend_mode_names.size());
1039  }
1040  ImGui::End();
1041 
1042  Canvas canvas;
1043  canvas.Scale(Vector2(0.2, 0.2));
1044  canvas.DrawPaint({.color = background});
1045  canvas.DrawPaint(
1046  {.color = foreground,
1047  .blend_mode = static_cast<BlendMode>(current_blend_index)});
1048  return canvas.EndRecordingAsPicture();
1049  };
1050  ASSERT_TRUE(OpenPlaygroundHere(callback));
1051 }

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

◆ TEST_P() [14/384]

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

Definition at line 954 of file aiks_unittests.cc.

954  {
955  Canvas canvas;
956  canvas.Scale(Vector2(0.2, 0.2));
957  canvas.DrawPaint({.color = Color::MediumTurquoise()});
958  canvas.DrawPaint({.color = Color::Color::OrangeRed().WithAlpha(0.5),
959  .blend_mode = BlendMode::kHue});
960  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
961 }

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

◆ TEST_P() [15/384]

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

Definition at line 2836 of file aiks_unittests.cc.

2836  {
2837  std::vector<Point> points = {
2838  {0, 0}, //
2839  {100, 100}, //
2840  {100, 0}, //
2841  {0, 100}, //
2842  {0, 0}, //
2843  {48, 48}, //
2844  {52, 52}, //
2845  };
2846  std::vector<PointStyle> caps = {
2847  PointStyle::kRound,
2848  PointStyle::kSquare,
2849  };
2850  Paint paint;
2851  paint.color = Color::Yellow().WithAlpha(0.5);
2852 
2853  Paint background;
2854  background.color = Color::Black();
2855 
2856  Canvas canvas;
2857  canvas.DrawPaint(background);
2858  canvas.Translate({200, 200});
2859  canvas.DrawPoints(points, 10, paint, PointStyle::kRound);
2860  canvas.Translate({150, 0});
2861  canvas.DrawPoints(points, 10, paint, PointStyle::kSquare);
2862 
2863  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2864 }

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

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

Definition at line 2930 of file aiks_unittests.cc.

2930  {
2931  auto texture = CreateTextureForFixture("table_mountain_nx.png",
2932  /*enable_mipmapping=*/true);
2933 
2934  std::vector<Point> points = {
2935  {0, 0}, //
2936  {100, 100}, //
2937  {100, 0}, //
2938  {0, 100}, //
2939  {0, 0}, //
2940  {48, 48}, //
2941  {52, 52}, //
2942  };
2943  std::vector<PointStyle> caps = {
2944  PointStyle::kRound,
2945  PointStyle::kSquare,
2946  };
2947  Paint paint;
2948  paint.color_source = ColorSource::MakeImage(texture, Entity::TileMode::kClamp,
2949  Entity::TileMode::kClamp, {}, {});
2950 
2951  Canvas canvas;
2952  canvas.Translate({200, 200});
2953  canvas.DrawPoints(points, 100, paint, PointStyle::kRound);
2954  canvas.Translate({150, 0});
2955  canvas.DrawPoints(points, 100, paint, PointStyle::kSquare);
2956 
2957  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2958 }

References impeller::Paint::color_source, impeller::Entity::kClamp, impeller::kRound, impeller::kSquare, impeller::ColorSource::MakeImage(), and impeller::Canvas::Translate().

◆ TEST_P() [17/384]

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

Definition at line 580 of file aiks_unittests.cc.

580  {
581  Canvas canvas;
582 
583  Paint red;
584  red.color = Color::Red();
585 
586  canvas.DrawCircle({250, 250}, 125, red);
587 
588  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
589 }

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

◆ TEST_P() [18/384]

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

Definition at line 603 of file aiks_unittests.cc.

603  {
604  Canvas canvas;
605 
606  Paint red;
607  red.color = Color::Red();
608 
609  Paint green;
610  green.color = Color::Green();
611 
612  Paint blue;
613  blue.color = Color::Blue();
614 
615  Paint save;
616  save.color = Color::Black();
617 
618  canvas.SaveLayer(save, Rect::MakeXYWH(0, 0, 50, 50));
619 
620  canvas.DrawRect(Rect::MakeXYWH(0, 0, 100, 100), red);
621  canvas.DrawRect(Rect::MakeXYWH(10, 10, 100, 100), green);
622  canvas.DrawRect(Rect::MakeXYWH(20, 20, 100, 100), blue);
623 
624  canvas.Restore();
625 
626  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
627 }

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

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

Definition at line 629 of file aiks_unittests.cc.

630  {
631  Canvas canvas;
632 
633  Paint red;
634  red.color = Color::Red();
635 
636  Paint green;
637  green.color = Color::Green();
638 
639  Paint blue;
640  blue.color = Color::Blue();
641 
642  Paint save;
643  save.color = Color::Black().WithAlpha(0.5);
644 
645  canvas.SaveLayer(save, Rect::MakeXYWH(0, 0, 100000, 100000));
646 
647  canvas.DrawRect(Rect::MakeXYWH(0, 0, 100, 100), red);
648  canvas.DrawRect(Rect::MakeXYWH(10, 10, 100, 100), green);
649  canvas.DrawRect(Rect::MakeXYWH(20, 20, 100, 100), blue);
650 
651  canvas.Restore();
652 
653  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
654 }

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

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

Definition at line 591 of file aiks_unittests.cc.

591  {
592  Canvas canvas;
593 
594  Paint red;
595  red.color = Color::Red();
596 
597  canvas.Skew(2, 5);
598  canvas.DrawRect(Rect::MakeXYWH(0, 0, 100, 100), red);
599 
600  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
601 }

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

◆ TEST_P() [21/384]

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

Definition at line 467 of file aiks_unittests.cc.

467  {
468  Canvas recorder_canvas;
469  Paint paint;
470  paint.color = Color{0.9568, 0.2627, 0.2118, 1.0};
471  recorder_canvas.DrawRect(Rect::MakeXYWH(100.0, 100.0, 600, 600), paint);
472  paint.color = Color{0.1294, 0.5882, 0.9529, 1.0};
473  recorder_canvas.DrawRect(Rect::MakeXYWH(200.0, 200.0, 600, 600), paint);
474 
475  Canvas canvas;
476  AiksContext renderer(GetContext(), nullptr);
477  paint.color = Color::BlackTransparent();
478  canvas.DrawPaint(paint);
479  Picture picture = recorder_canvas.EndRecordingAsPicture();
480  auto image = picture.ToImage(renderer, ISize{1000, 1000});
481  if (image) {
482  canvas.DrawImage(image, Point(), Paint());
483  paint.color = Color{0.1, 0.1, 0.1, 0.2};
484  canvas.DrawRect(Rect::MakeSize(ISize{1000, 1000}), paint);
485  }
486 
487  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
488 }

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

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

Definition at line 2680 of file aiks_unittests.cc.

2680  {
2681  Canvas canvas;
2682  canvas.DrawCircle({100, 100}, 50, {.color = Color::CornflowerBlue()});
2683  canvas.DrawCircle({300, 200}, 100, {.color = Color::GreenYellow()});
2684  canvas.DrawCircle({140, 170}, 75, {.color = Color::DarkMagenta()});
2685  canvas.DrawCircle({180, 120}, 100, {.color = Color::OrangeRed()});
2686  canvas.ClipRRect(Rect::MakeLTRB(75, 50, 375, 275), {20, 20});
2687  canvas.SaveLayer({.blend_mode = BlendMode::kSource}, std::nullopt,
2688  ImageFilter::MakeBlur(Sigma(30.0), Sigma(30.0),
2689  FilterContents::BlurStyle::kNormal,
2690  Entity::TileMode::kClamp));
2691  canvas.Restore();
2692 
2693  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2694 }

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

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

Definition at line 2696 of file aiks_unittests.cc.

2696  {
2697  Canvas canvas;
2698  canvas.DrawCircle({400, 400}, 300, {.color = Color::Green()});
2699  canvas.SaveLayer({.blend_mode = BlendMode::kSource}, std::nullopt,
2700  ImageFilter::MakeBlur(Sigma(999999), Sigma(999999),
2701  FilterContents::BlurStyle::kNormal,
2702  Entity::TileMode::kClamp));
2703  canvas.Restore();
2704 
2705  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2706 }

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

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

Definition at line 2657 of file aiks_unittests.cc.

2657  {
2658  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
2659  auto [a, b] = IMPELLER_PLAYGROUND_LINE(Point(50, 50), Point(300, 200), 30,
2660  Color::White(), Color::White());
2661 
2662  Canvas canvas;
2663  canvas.DrawCircle({100, 100}, 50, {.color = Color::CornflowerBlue()});
2664  canvas.DrawCircle({300, 200}, 100, {.color = Color::GreenYellow()});
2665  canvas.DrawCircle({140, 170}, 75, {.color = Color::DarkMagenta()});
2666  canvas.DrawCircle({180, 120}, 100, {.color = Color::OrangeRed()});
2667  canvas.ClipRRect(Rect::MakeLTRB(a.x, a.y, b.x, b.y), {20, 20});
2668  canvas.SaveLayer({.blend_mode = BlendMode::kSource}, std::nullopt,
2669  ImageFilter::MakeBlur(Sigma(20.0), Sigma(20.0),
2670  FilterContents::BlurStyle::kNormal,
2671  Entity::TileMode::kClamp));
2672  canvas.Restore();
2673 
2674  return canvas.EndRecordingAsPicture();
2675  };
2676 
2677  ASSERT_TRUE(OpenPlaygroundHere(callback));
2678 }

References impeller::Canvas::ClipRRect(), impeller::Color::CornflowerBlue(), impeller::Color::DarkMagenta(), impeller::Canvas::DrawCircle(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::GreenYellow(), IMPELLER_PLAYGROUND_LINE, 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/384]

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

Definition at line 2708 of file aiks_unittests.cc.

2708  {
2709  Canvas canvas;
2710  canvas.ClipRect(Rect::MakeXYWH(100, 150, 400, 400));
2711  canvas.DrawCircle(
2712  {400, 400}, 200,
2713  {
2714  .color = Color::Green(),
2715  .image_filter = ImageFilter::MakeBlur(
2716  Sigma(20.0), Sigma(20.0), FilterContents::BlurStyle::kNormal,
2717  Entity::TileMode::kClamp),
2718  });
2719  canvas.Restore();
2720 
2721  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2722 }

References impeller::Canvas::ClipRect(), impeller::Canvas::DrawCircle(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::Entity::kClamp, impeller::FilterContents::kNormal, impeller::ImageFilter::MakeBlur(), impeller::TRect< Scalar >::MakeXYWH(), and impeller::Canvas::Restore().

◆ TEST_P() [26/384]

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

Definition at line 1766 of file aiks_unittests.cc.

1766  {
1767  Canvas canvas;
1768 
1769  canvas.DrawPaint({.color = Color::White()});
1770 
1771  // Draw a green circle on the screen.
1772  {
1773  // Increase the clip depth for the savelayer to contend with.
1774  canvas.ClipPath(PathBuilder{}.AddCircle({100, 100}, 50).TakePath());
1775 
1776  canvas.SaveLayer({}, Rect::MakeXYWH(50, 50, 100, 100));
1777 
1778  // Fill the layer with white.
1779  canvas.DrawRect(Rect::MakeSize(Size{400, 400}), {.color = Color::White()});
1780  // Fill the layer with green, but do so with a color blend that can't be
1781  // collapsed into the parent pass.
1782  // TODO(jonahwilliams): this blend mode was changed from color burn to
1783  // hardlight to work around https://github.com/flutter/flutter/issues/136554
1784  // .
1785  canvas.DrawRect(
1786  Rect::MakeSize(Size{400, 400}),
1787  {.color = Color::Green(), .blend_mode = BlendMode::kHardLight});
1788  }
1789 
1790  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1791 }

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

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

Definition at line 2767 of file aiks_unittests.cc.

2767  {
2768  if (!BackendSupportsFragmentProgram()) {
2769  GTEST_SKIP_("This backend doesn't support runtime effects.");
2770  }
2771 
2772  auto runtime_stages =
2773  OpenAssetAsRuntimeStage("runtime_stage_example.frag.iplr");
2774 
2775  auto runtime_stage =
2776  runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
2777  ASSERT_TRUE(runtime_stage);
2778  ASSERT_TRUE(runtime_stage->IsDirty());
2779 
2780  struct FragUniforms {
2781  Vector2 iResolution;
2782  Scalar iTime;
2783  } frag_uniforms = {.iResolution = Vector2(400, 400), .iTime = 100.0};
2784  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
2785  uniform_data->resize(sizeof(FragUniforms));
2786  memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
2787 
2788  std::vector<RuntimeEffectContents::TextureInput> texture_inputs;
2789 
2790  Paint paint;
2791  paint.color_source = ColorSource::MakeRuntimeEffect(
2792  runtime_stage, uniform_data, texture_inputs);
2793 
2794  Canvas canvas;
2795  canvas.Save();
2796  canvas.ClipRRect(Rect::MakeXYWH(0, 0, 400, 400), {10.0, 10.0},
2797  Entity::ClipOperation::kIntersect);
2798  canvas.DrawRect(Rect::MakeXYWH(0, 0, 400, 400), paint);
2799  canvas.Restore();
2800 
2801  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2802 }

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

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

Definition at line 385 of file aiks_path_unittests.cc.

385  {
386  Canvas canvas;
387  Paint paint;
388  paint.color = Color::Fuchsia();
389  canvas.ClipPath(
390  PathBuilder{}.AddRect(Rect::MakeXYWH(0, 0, 500, 500)).TakePath());
391  canvas.DrawPath(PathBuilder{}.AddCircle({500, 500}, 250).TakePath(), paint);
392  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
393 }

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

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

Definition at line 81 of file aiks_unittests.cc.

81  {
82  Canvas canvas;
83  Paint paint;
84  paint.color = Color::Blue();
85  canvas.DrawPath(PathBuilder{}
86  .AddRect(Rect::MakeXYWH(100.0, 100.0, 100.0, 100.0))
87  .TakePath(),
88  paint);
89  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
90 }

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

◆ TEST_P() [30/384]

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

Definition at line 114 of file aiks_unittests.cc.

114  {
115  Canvas canvas;
116  Paint paint;
117  paint.color = Color::Red();
118  paint.color_filter =
119  ColorFilter::MakeBlend(BlendMode::kSourceOver, Color::Yellow());
120  paint.invert_colors = true;
121 
122  canvas.DrawRect(Rect::MakeLTRB(0, 0, 100, 100), paint);
123  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
124 }

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

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

Definition at line 126 of file aiks_unittests.cc.

126  {
127  Canvas canvas;
128  Paint paint;
129  paint.color = Color::Red();
130  paint.color_filter =
131  ColorFilter::MakeBlend(BlendMode::kSourceOver, Color::Yellow());
132  paint.invert_colors = true;
133 
134  canvas.DrawPaint(paint);
135  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
136 }

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

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

Definition at line 559 of file aiks_gradient_unittests.cc.

559  {
560  Scalar size = 256;
561  Canvas canvas;
562  Paint paint;
563  paint.color = Color::White();
564  canvas.DrawRect(Rect::MakeXYWH(0, 0, size * 3, size * 3), paint);
565  std::vector<Color> colors = {Color::MakeRGBA8(0xF4, 0x43, 0x36, 0xFF),
566  Color::MakeRGBA8(0xFF, 0xEB, 0x3B, 0xFF),
567  Color::MakeRGBA8(0x4c, 0xAF, 0x50, 0xFF),
568  Color::MakeRGBA8(0x21, 0x96, 0xF3, 0xFF)};
569  std::vector<Scalar> stops = {0.0, 1.f / 3.f, 2.f / 3.f, 1.0};
570  std::array<std::tuple<Point, float, Point, float>, 8> array{
571  std::make_tuple(Point{size / 2.f, size / 2.f}, 0.f,
572  Point{size / 2.f, size / 2.f}, size / 2.f),
573  std::make_tuple(Point{size / 2.f, size / 2.f}, size / 4.f,
574  Point{size / 2.f, size / 2.f}, size / 2.f),
575  std::make_tuple(Point{size / 4.f, size / 4.f}, 0.f,
576  Point{size / 2.f, size / 2.f}, size / 2.f),
577  std::make_tuple(Point{size / 4.f, size / 4.f}, size / 2.f,
578  Point{size / 2.f, size / 2.f}, 0),
579  std::make_tuple(Point{size / 4.f, size / 4.f}, size / 4.f,
580  Point{size / 2.f, size / 2.f}, size / 2.f),
581  std::make_tuple(Point{size / 4.f, size / 4.f}, size / 16.f,
582  Point{size / 2.f, size / 2.f}, size / 8.f),
583  std::make_tuple(Point{size / 4.f, size / 4.f}, size / 8.f,
584  Point{size / 2.f, size / 2.f}, size / 16.f),
585  std::make_tuple(Point{size / 8.f, size / 8.f}, size / 8.f,
586  Point{size / 2.f, size / 2.f}, size / 8.f),
587  };
588  for (int i = 0; i < 8; i++) {
589  canvas.Save();
590  canvas.Translate({(i % 3) * size, i / 3 * size, 0});
591  paint.color_source = ColorSource::MakeConicalGradient(
592  std::get<0>(array[i]), std::get<1>(array[i]), colors, stops,
593  std::get<2>(array[i]), std::get<3>(array[i]), Entity::TileMode::kClamp,
594  {});
595  canvas.DrawRect(Rect::MakeXYWH(0, 0, size, size), paint);
596  canvas.Restore();
597  }
598  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
599 }

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

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

Definition at line 190 of file aiks_gradient_unittests.cc.

190  {
192 }

References CanRenderConicalGradientWithDithering().

◆ TEST_P() [34/384]

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

Definition at line 194 of file aiks_gradient_unittests.cc.

194  {
196 }

References CanRenderConicalGradientWithDithering().

◆ TEST_P() [35/384]

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

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

Definition at line 2630 of file aiks_unittests.cc.

2630  {
2631  Canvas canvas;
2632 
2633  canvas.DrawPaint({.color = Color::Red()});
2634  // Draw an empty savelayer with a destructive blend mode, which will replace
2635  // the entire red screen with fully transparent black, except for the green
2636  // circle drawn within the layer.
2637  canvas.SaveLayer({.blend_mode = BlendMode::kSource});
2638  canvas.DrawCircle({300, 300}, 100, {.color = Color::Green()});
2639  canvas.Restore();
2640 
2641  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2642 }

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

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

Definition at line 344 of file aiks_unittests.cc.

344  {
345  Paint paint;
346  Canvas canvas;
347  canvas.Translate({400, 400});
348 
349  // Limit drawing to face circle with a clip.
350  canvas.ClipPath(PathBuilder{}.AddCircle(Point(), 200).TakePath());
351  canvas.Save();
352 
353  // Cut away eyes/mouth using difference clips.
354  canvas.ClipPath(PathBuilder{}.AddCircle({-100, -50}, 30).TakePath(),
355  Entity::ClipOperation::kDifference);
356  canvas.ClipPath(PathBuilder{}.AddCircle({100, -50}, 30).TakePath(),
357  Entity::ClipOperation::kDifference);
358  canvas.ClipPath(PathBuilder{}
359  .AddQuadraticCurve({-100, 50}, {0, 150}, {100, 50})
360  .TakePath(),
361  Entity::ClipOperation::kDifference);
362 
363  // Draw a huge yellow rectangle to prove the clipping works.
364  paint.color = Color::Yellow();
365  canvas.DrawRect(Rect::MakeXYWH(-1000, -1000, 2000, 2000), paint);
366 
367  // Remove the difference clips and draw hair that partially covers the eyes.
368  canvas.Restore();
369  paint.color = Color::Maroon();
370  canvas.DrawPath(PathBuilder{}
371  .MoveTo({200, -200})
372  .HorizontalLineTo(-200)
373  .VerticalLineTo(-40)
374  .CubicCurveTo({0, -40}, {0, -80}, {200, -80})
375  .TakePath(),
376  paint);
377 
378  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
379 }

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

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(std::move(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() [39/384]

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

Definition at line 440 of file aiks_unittests.cc.

440  {
441  Canvas canvas;
442  Paint paint;
443 
444  std::vector<Color> colors = {Color{0.9568, 0.2627, 0.2118, 1.0},
445  Color{0.1294, 0.5882, 0.9529, 1.0}};
446  std::vector<Scalar> stops = {
447  0.0,
448  1.0,
449  };
450 
451  paint.color_source = ColorSource::MakeLinearGradient(
452  {0, 0}, {100, 100}, std::move(colors), std::move(stops),
453  Entity::TileMode::kRepeat, {});
454 
455  canvas.Save();
456  canvas.Translate({100, 100, 0});
457  canvas.DrawRect(Rect::MakeXYWH(0, 0, 200, 200), paint);
458  canvas.Restore();
459 
460  canvas.Save();
461  canvas.Translate({100, 400, 0});
462  canvas.DrawCircle({100, 100}, 100, paint);
463  canvas.Restore();
464  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
465 }

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

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

Definition at line 831 of file aiks_unittests.cc.

831  {
832  Canvas canvas;
833  canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
834 
835  ASSERT_TRUE(RenderTextInCanvasSkia(
836  GetContext(), canvas, "😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊", kFontFixture));
837  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
838 }

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

◆ TEST_P() [41/384]

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

Definition at line 853 of file aiks_unittests.cc.

853  {
854  Canvas canvas;
855  canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
856 
857  ASSERT_TRUE(RenderTextInCanvasSkia(
858  GetContext(), canvas, "😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊", kFontFixture,
859  {.color = Color::Black().WithAlpha(0.5)}));
860  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
861 }

References impeller::Color::Black(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), kFontFixture, RenderTextInCanvasSkia(), and impeller::Color::WithAlpha().

◆ TEST_P() [42/384]

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

Definition at line 840 of file aiks_unittests.cc.

840  {
841  Canvas canvas;
842  canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
843 
844  ASSERT_TRUE(RenderTextInCanvasSkia(
845  GetContext(), canvas, "😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊", kFontFixture,
846  TextRenderOptions{.color = Color::Blue(),
847  .mask_blur_descriptor = Paint::MaskBlurDescriptor{
848  .style = FilterContents::BlurStyle::kNormal,
849  .sigma = Sigma(4)}}));
850  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
851 }

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

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

Definition at line 2745 of file aiks_unittests.cc.

2745  {
2746  // This case triggers the ForegroundAdvancedBlend path. The color filter
2747  // should apply to the color only, and respect the alpha mask.
2748  Canvas canvas;
2749  canvas.ClipRect(Rect::MakeXYWH(100, 150, 400, 400));
2750  canvas.DrawCircle({400, 400}, 200,
2751  {
2752  .color = Color::Grey(),
2753  .color_filter = ColorFilter::MakeBlend(
2754  BlendMode::kColor, Color::Green()),
2755  .mask_blur_descriptor =
2756  Paint::MaskBlurDescriptor{
2757  .style = FilterContents::BlurStyle::kNormal,
2758  .sigma = Radius(20),
2759  },
2760  });
2761  canvas.Restore();
2762 
2763  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2764 }

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

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

Definition at line 2724 of file aiks_unittests.cc.

2724  {
2725  // This case triggers the ForegroundPorterDuffBlend path. The color filter
2726  // should apply to the color only, and respect the alpha mask.
2727  Canvas canvas;
2728  canvas.ClipRect(Rect::MakeXYWH(100, 150, 400, 400));
2729  canvas.DrawCircle({400, 400}, 200,
2730  {
2731  .color = Color::White(),
2732  .color_filter = ColorFilter::MakeBlend(
2733  BlendMode::kSource, Color::Green()),
2734  .mask_blur_descriptor =
2735  Paint::MaskBlurDescriptor{
2736  .style = FilterContents::BlurStyle::kNormal,
2737  .sigma = Radius(20),
2738  },
2739  });
2740  canvas.Restore();
2741 
2742  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2743 }

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

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

Definition at line 601 of file aiks_gradient_unittests.cc.

601  {
602  std::vector<Color> colors = {Color::MakeRGBA8(0xF4, 0x43, 0x36, 0xFF),
603  Color::MakeRGBA8(0xFF, 0xEB, 0x3B, 0xFF),
604  Color::MakeRGBA8(0x4c, 0xAF, 0x50, 0xFF),
605  Color::MakeRGBA8(0x21, 0x96, 0xF3, 0xFF)};
606  std::vector<Scalar> stops = {0.0, 1.f / 3.f, 2.f / 3.f, 1.0};
607 
608  std::array<ColorSource, 3> color_sources = {
609  ColorSource::MakeLinearGradient({0, 0}, {100, 100}, colors, stops,
610  Entity::TileMode::kDecal, {}),
611  ColorSource::MakeRadialGradient({100, 100}, 100, colors, stops,
612  Entity::TileMode::kDecal, {}),
613  ColorSource::MakeSweepGradient({100, 100}, Degrees(45), Degrees(135),
614  colors, stops, Entity::TileMode::kDecal,
615  {}),
616  };
617 
618  Canvas canvas;
619  Paint paint;
620  paint.color = Color::White();
621  canvas.DrawRect(Rect::MakeLTRB(0, 0, 605, 205), paint);
622  for (int i = 0; i < 3; i++) {
623  canvas.Save();
624  canvas.Translate({i * 200.0f, 0, 0});
625  paint.color_source = color_sources[i];
626  canvas.DrawRect(Rect::MakeLTRB(0, 0, 200, 200), paint);
627  canvas.Restore();
628  }
629  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
630 }

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

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

Definition at line 515 of file aiks_unittests.cc.

515  {
516  Canvas canvas;
517 
518  Paint red;
519  red.color = Color::Red();
520  Paint green;
521  green.color = Color::Green().WithAlpha(0.5);
522  Paint blue;
523  blue.color = Color::Blue();
524 
525  Paint alpha;
526  alpha.color = Color::Red().WithAlpha(0.5);
527 
528  canvas.SaveLayer(alpha);
529 
530  canvas.DrawRect(Rect::MakeXYWH(000, 000, 100, 100), red);
531  canvas.DrawRect(Rect::MakeXYWH(020, 020, 100, 100), green);
532  canvas.DrawRect(Rect::MakeXYWH(040, 040, 100, 100), blue);
533 
534  canvas.Restore();
535 
536  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
537 }

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

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

Definition at line 92 of file aiks_unittests.cc.

92  {
93  Canvas canvas;
94  Paint paint;
95  auto image = std::make_shared<Image>(CreateTextureForFixture("kalimba.jpg"));
96  paint.color = Color::Red();
97  canvas.DrawImage(image, Point::MakeXY(100.0, 100.0), paint);
98  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
99 }

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

◆ TEST_P() [48/384]

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

Definition at line 236 of file aiks_unittests.cc.

236  {
237  Canvas canvas;
238  Paint paint;
239  auto image = std::make_shared<Image>(CreateTextureForFixture("kalimba.jpg"));
240  Size image_half_size = Size(image->GetSize()) * 0.5;
241 
242  // Render the bottom right quarter of the source image in a stretched rect.
243  auto source_rect = Rect::MakeSize(image_half_size);
244  source_rect = source_rect.Shift(Point(image_half_size));
245 
246  canvas.DrawImageRect(image, source_rect, Rect::MakeXYWH(100, 100, 600, 600),
247  paint);
248  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
249 }

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

◆ TEST_P() [49/384]

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

Definition at line 101 of file aiks_unittests.cc.

101  {
102  Canvas canvas;
103  Paint paint;
104  auto image = std::make_shared<Image>(CreateTextureForFixture("kalimba.jpg"));
105  paint.color = Color::Red();
106  paint.color_filter =
107  ColorFilter::MakeBlend(BlendMode::kSourceOver, Color::Yellow());
108  paint.invert_colors = true;
109 
110  canvas.DrawImage(image, Point::MakeXY(100.0, 100.0), paint);
111  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
112 }

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

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

Definition at line 814 of file aiks_unittests.cc.

814  {
815  Canvas canvas;
816  canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
817 
818  ASSERT_TRUE(RenderTextInCanvasSkia(
819  GetContext(), canvas, "the quick brown fox jumped over the lazy dog!.?",
820  "HomemadeApple.ttf"));
821  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
822 }

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

◆ TEST_P() [51/384]

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

Definition at line 48 of file aiks_gradient_unittests.cc.

48  {
49  CanRenderLinearGradient(this, Entity::TileMode::kClamp);
50 }

References impeller::Entity::kClamp.

◆ TEST_P() [52/384]

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

Definition at line 57 of file aiks_gradient_unittests.cc.

57  {
58  CanRenderLinearGradient(this, Entity::TileMode::kDecal);
59 }

References impeller::Entity::kDecal.

◆ TEST_P() [53/384]

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

Definition at line 61 of file aiks_gradient_unittests.cc.

61  {
62  Canvas canvas;
63  canvas.Scale(GetContentScale());
64  Paint paint;
65  canvas.Translate({100.0f, 0, 0});
66 
67  std::vector<Color> colors = {Color{0.9568, 0.2627, 0.2118, 1.0},
68  Color{0.1294, 0.5882, 0.9529, 0.0}};
69  std::vector<Scalar> stops = {0.0, 1.0};
70 
71  paint.color_source = ColorSource::MakeLinearGradient(
72  {0, 0}, {200, 200}, std::move(colors), std::move(stops),
73  Entity::TileMode::kDecal, {});
74  // Overlay the gradient with 25% green. This should appear as the entire
75  // rectangle being drawn with 25% green, including the border area outside the
76  // decal gradient.
77  paint.color_filter = ColorFilter::MakeBlend(BlendMode::kSourceOver,
78  Color::Green().WithAlpha(0.25));
79 
80  paint.color = Color(1.0, 1.0, 1.0, 1.0);
81  canvas.DrawRect(Rect::MakeXYWH(0, 0, 600, 600), paint);
82  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
83 }

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

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

Definition at line 260 of file aiks_gradient_unittests.cc.

260  {
261  CanRenderLinearGradientManyColors(this, Entity::TileMode::kClamp);
262 }

References impeller::Entity::kClamp.

◆ TEST_P() [55/384]

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

Definition at line 269 of file aiks_gradient_unittests.cc.

269  {
270  CanRenderLinearGradientManyColors(this, Entity::TileMode::kDecal);
271 }

References impeller::Entity::kDecal.

◆ TEST_P() [56/384]

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

Definition at line 266 of file aiks_gradient_unittests.cc.

266  {
267  CanRenderLinearGradientManyColors(this, Entity::TileMode::kMirror);
268 }

References impeller::Entity::kMirror.

◆ TEST_P() [57/384]

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

Definition at line 263 of file aiks_gradient_unittests.cc.

263  {
264  CanRenderLinearGradientManyColors(this, Entity::TileMode::kRepeat);
265 }

References impeller::Entity::kRepeat.

◆ TEST_P() [58/384]

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

Definition at line 303 of file aiks_gradient_unittests.cc.

303  {
304  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
305  const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
306  const Entity::TileMode tile_modes[] = {
307  Entity::TileMode::kClamp, Entity::TileMode::kRepeat,
308  Entity::TileMode::kMirror, Entity::TileMode::kDecal};
309 
310  static int selected_tile_mode = 0;
311  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
312  ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
313  sizeof(tile_mode_names) / sizeof(char*));
314  static Matrix matrix = {
315  1, 0, 0, 0, //
316  0, 1, 0, 0, //
317  0, 0, 1, 0, //
318  0, 0, 0, 1 //
319  };
320  std::string label = "##1";
321  for (int i = 0; i < 4; i++) {
322  ImGui::InputScalarN(label.c_str(), ImGuiDataType_Float, &(matrix.vec[i]),
323  4, NULL, NULL, "%.2f", 0);
324  label[2]++;
325  }
326  ImGui::End();
327 
328  Canvas canvas;
329  Paint paint;
330  canvas.Translate({100.0, 100.0, 0});
331  auto tile_mode = tile_modes[selected_tile_mode];
332 
333  std::vector<Color> colors = {
334  Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0},
335  Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0},
336  Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0},
337  Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0},
338  Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0},
339  Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0},
340  Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}};
341  std::vector<Scalar> stops = {
342  0.0, 2.0 / 62.0, 4.0 / 62.0, 8.0 / 62.0, 16.0 / 62.0, 32.0 / 62.0, 1.0,
343  };
344 
345  paint.color_source = ColorSource::MakeLinearGradient(
346  {0, 0}, {200, 200}, std::move(colors), std::move(stops), tile_mode, {});
347 
348  canvas.DrawRect(Rect::MakeXYWH(0, 0, 600, 600), paint);
349  return canvas.EndRecordingAsPicture();
350  };
351  ASSERT_TRUE(OpenPlaygroundHere(callback));
352 }

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

◆ TEST_P() [59/384]

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

Definition at line 354 of file aiks_gradient_unittests.cc.

354  {
355  Canvas canvas;
356 
357  Paint paint = {
358  .color = Color::White(),
359  .color_source = ColorSource::MakeLinearGradient(
360  {200, 200}, {400, 400},
361  {Color::Red(), Color::White(), Color::Red(), Color::White(),
362  Color::Red(), Color::White(), Color::Red(), Color::White(),
363  Color::Red(), Color::White(), Color::Red()},
364  {0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0},
365  Entity::TileMode::kClamp, {}),
366  .mask_blur_descriptor =
367  Paint::MaskBlurDescriptor{
368  .style = FilterContents::BlurStyle::kNormal,
369  .sigma = Sigma(20),
370  },
371  };
372 
373  canvas.DrawCircle({300, 300}, 200, paint);
374  canvas.DrawRect(Rect::MakeLTRB(100, 300, 500, 600), paint);
375 
376  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
377 }

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

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

Definition at line 54 of file aiks_gradient_unittests.cc.

54  {
55  CanRenderLinearGradient(this, Entity::TileMode::kMirror);
56 }

References impeller::Entity::kMirror.

◆ TEST_P() [61/384]

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

Definition at line 51 of file aiks_gradient_unittests.cc.

51  {
52  CanRenderLinearGradient(this, Entity::TileMode::kRepeat);
53 }

References impeller::Entity::kRepeat.

◆ TEST_P() [62/384]

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

Definition at line 299 of file aiks_gradient_unittests.cc.

299  {
300  CanRenderLinearGradientWayManyColors(this, Entity::TileMode::kClamp);
301 }

References impeller::Entity::kClamp.

◆ TEST_P() [63/384]

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

Definition at line 105 of file aiks_gradient_unittests.cc.

105  {
107 }

References CanRenderLinearGradientWithDithering().

◆ TEST_P() [64/384]

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

Definition at line 109 of file aiks_gradient_unittests.cc.

109  {
111 } // namespace

References CanRenderLinearGradientWithDithering().

◆ TEST_P() [65/384]

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

Definition at line 220 of file aiks_gradient_unittests.cc.

220  {
221  CanRenderLinearGradientWithOverlappingStops(this, Entity::TileMode::kClamp);
222 }

References impeller::Entity::kClamp.

◆ TEST_P() [66/384]

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

Definition at line 2644 of file aiks_unittests.cc.

2644  {
2645  Canvas canvas;
2646  canvas.DrawCircle({400, 400}, 300,
2647  {.color = Color::Green(),
2648  .mask_blur_descriptor = Paint::MaskBlurDescriptor{
2649  .style = FilterContents::BlurStyle::kNormal,
2650  .sigma = Sigma(99999),
2651  }});
2652  canvas.Restore();
2653 
2654  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2655 }

References impeller::Canvas::DrawCircle(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::FilterContents::kNormal, impeller::Canvas::Restore(), and impeller::Paint::MaskBlurDescriptor::style.

◆ TEST_P() [67/384]

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

Definition at line 331 of file aiks_unittests.cc.

331  {
332  Canvas canvas;
333  Paint paint;
334  paint.color = Color::Fuchsia();
335  canvas.Save();
336  canvas.ClipPath(PathBuilder{}.AddCircle({200, 400}, 300).TakePath());
337  canvas.Restore();
338  canvas.ClipPath(PathBuilder{}.AddCircle({600, 400}, 300).TakePath());
339  canvas.ClipPath(PathBuilder{}.AddCircle({400, 600}, 300).TakePath());
340  canvas.DrawRect(Rect::MakeXYWH(200, 200, 400, 400), paint);
341  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
342 }

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

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

2580  {
2581  Canvas canvas;
2582  canvas.debug_options.offscreen_texture_checkerboard = true;
2583 
2584  canvas.DrawPaint({.color = Color::AntiqueWhite()});
2585  canvas.DrawCircle({400, 300}, 200,
2586  {.color = Color::CornflowerBlue().WithAlpha(0.75)});
2587 
2588  canvas.SaveLayer({.blend_mode = BlendMode::kMultiply});
2589  {
2590  canvas.DrawCircle({500, 400}, 200,
2591  {.color = Color::DarkBlue().WithAlpha(0.75)});
2592  canvas.DrawCircle({550, 450}, 200,
2593  {.color = Color::LightCoral().WithAlpha(0.75),
2594  .blend_mode = BlendMode::kLuminosity});
2595  }
2596  canvas.Restore();
2597 
2598  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2599 }

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

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

Definition at line 379 of file aiks_gradient_unittests.cc.

379  {
380  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
381  const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
382  const Entity::TileMode tile_modes[] = {
383  Entity::TileMode::kClamp, Entity::TileMode::kRepeat,
384  Entity::TileMode::kMirror, Entity::TileMode::kDecal};
385 
386  static int selected_tile_mode = 0;
387  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
388  ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
389  sizeof(tile_mode_names) / sizeof(char*));
390  static Matrix matrix = {
391  1, 0, 0, 0, //
392  0, 1, 0, 0, //
393  0, 0, 1, 0, //
394  0, 0, 0, 1 //
395  };
396  std::string label = "##1";
397  for (int i = 0; i < 4; i++) {
398  ImGui::InputScalarN(label.c_str(), ImGuiDataType_Float, &(matrix.vec[i]),
399  4, NULL, NULL, "%.2f", 0);
400  label[2]++;
401  }
402  ImGui::End();
403 
404  Canvas canvas;
405  Paint paint;
406  canvas.Translate({100.0, 100.0, 0});
407  auto tile_mode = tile_modes[selected_tile_mode];
408 
409  std::vector<Color> colors = {Color{0.9568, 0.2627, 0.2118, 1.0},
410  Color{0.1294, 0.5882, 0.9529, 1.0}};
411  std::vector<Scalar> stops = {0.0, 1.0};
412 
413  paint.color_source = ColorSource::MakeRadialGradient(
414  {100, 100}, 100, std::move(colors), std::move(stops), tile_mode, {});
415 
416  canvas.DrawRect(Rect::MakeXYWH(0, 0, 600, 600), paint);
417  return canvas.EndRecordingAsPicture();
418  };
419  ASSERT_TRUE(OpenPlaygroundHere(callback));
420 }

References impeller::Paint::color_source, impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kClamp, impeller::Entity::kDecal, impeller::Entity::kMirror, impeller::Entity::kRepeat, impeller::ColorSource::MakeRadialGradient(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Canvas::Translate(), and impeller::Matrix::vec.

◆ TEST_P() [70/384]

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

Definition at line 422 of file aiks_gradient_unittests.cc.

422  {
423  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
424  const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
425  const Entity::TileMode tile_modes[] = {
426  Entity::TileMode::kClamp, Entity::TileMode::kRepeat,
427  Entity::TileMode::kMirror, Entity::TileMode::kDecal};
428 
429  static int selected_tile_mode = 0;
430  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
431  ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
432  sizeof(tile_mode_names) / sizeof(char*));
433  static Matrix matrix = {
434  1, 0, 0, 0, //
435  0, 1, 0, 0, //
436  0, 0, 1, 0, //
437  0, 0, 0, 1 //
438  };
439  std::string label = "##1";
440  for (int i = 0; i < 4; i++) {
441  ImGui::InputScalarN(label.c_str(), ImGuiDataType_Float, &(matrix.vec[i]),
442  4, NULL, NULL, "%.2f", 0);
443  label[2]++;
444  }
445  ImGui::End();
446 
447  Canvas canvas;
448  Paint paint;
449  canvas.Translate({100.0, 100.0, 0});
450  auto tile_mode = tile_modes[selected_tile_mode];
451 
452  std::vector<Color> colors = {
453  Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0},
454  Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0},
455  Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0},
456  Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0},
457  Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0},
458  Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0},
459  Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}};
460  std::vector<Scalar> stops = {
461  0.0,
462  (1.0 / 6.0) * 1,
463  (1.0 / 6.0) * 2,
464  (1.0 / 6.0) * 3,
465  (1.0 / 6.0) * 4,
466  (1.0 / 6.0) * 5,
467  1.0,
468  };
469 
470  paint.color_source = ColorSource::MakeRadialGradient(
471  {100, 100}, 100, std::move(colors), std::move(stops), tile_mode, {});
472 
473  canvas.DrawRect(Rect::MakeXYWH(0, 0, 600, 600), paint);
474  return canvas.EndRecordingAsPicture();
475  };
476  ASSERT_TRUE(OpenPlaygroundHere(callback));
477 }

References impeller::Paint::color_source, impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kClamp, impeller::Entity::kDecal, impeller::Entity::kMirror, impeller::Entity::kRepeat, impeller::ColorSource::MakeRadialGradient(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Canvas::Translate(), and impeller::Matrix::vec.

◆ TEST_P() [71/384]

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

Definition at line 132 of file aiks_gradient_unittests.cc.

132  {
134 }

References CanRenderRadialGradientWithDithering().

◆ TEST_P() [72/384]

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

Definition at line 136 of file aiks_gradient_unittests.cc.

136  {
138 }

References CanRenderRadialGradientWithDithering().

◆ TEST_P() [73/384]

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

Definition at line 656 of file aiks_unittests.cc.

656  {
657  Canvas canvas;
658 
659  Paint paint;
660  paint.color = Color::Red();
661 
662  PathBuilder::RoundingRadii radii;
663  radii.top_left = {50, 25};
664  radii.top_right = {25, 50};
665  radii.bottom_right = {50, 25};
666  radii.bottom_left = {25, 50};
667 
668  auto path = PathBuilder{}
669  .AddRoundedRect(Rect::MakeXYWH(100, 100, 500, 500), radii)
670  .TakePath();
671 
672  canvas.DrawPath(std::move(path), paint);
673 
674  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
675 }

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

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

Definition at line 251 of file aiks_unittests.cc.

251  {
252  Canvas canvas;
253  canvas.Scale(GetContentScale());
254  Paint paint;
255 
256  paint.color = Color::White();
257  canvas.DrawPaint(paint);
258 
259  auto draw = [&canvas](const Paint& paint, Scalar x, Scalar y) {
260  canvas.Save();
261  canvas.Translate({x, y});
262  {
263  canvas.Save();
264  canvas.ClipRect(Rect::MakeLTRB(50, 50, 150, 150));
265  canvas.DrawPaint(paint);
266  canvas.Restore();
267  }
268  {
269  canvas.Save();
270  canvas.ClipOval(Rect::MakeLTRB(200, 50, 300, 150));
271  canvas.DrawPaint(paint);
272  canvas.Restore();
273  }
274  {
275  canvas.Save();
276  canvas.ClipRRect(Rect::MakeLTRB(50, 200, 150, 300), {20, 20});
277  canvas.DrawPaint(paint);
278  canvas.Restore();
279  }
280  {
281  canvas.Save();
282  canvas.ClipRRect(Rect::MakeLTRB(200, 230, 300, 270), {20, 20});
283  canvas.DrawPaint(paint);
284  canvas.Restore();
285  }
286  {
287  canvas.Save();
288  canvas.ClipRRect(Rect::MakeLTRB(230, 200, 270, 300), {20, 20});
289  canvas.DrawPaint(paint);
290  canvas.Restore();
291  }
292  canvas.Restore();
293  };
294 
295  paint.color = Color::Blue();
296  draw(paint, 0, 0);
297 
298  std::vector<Color> gradient_colors = {
299  Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0},
300  Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0},
301  Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0},
302  Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0},
303  Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0},
304  Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0},
305  Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}};
306  std::vector<Scalar> stops = {
307  0.0,
308  (1.0 / 6.0) * 1,
309  (1.0 / 6.0) * 2,
310  (1.0 / 6.0) * 3,
311  (1.0 / 6.0) * 4,
312  (1.0 / 6.0) * 5,
313  1.0,
314  };
315  auto texture = CreateTextureForFixture("airplane.jpg",
316  /*enable_mipmapping=*/true);
317 
318  paint.color_source = ColorSource::MakeRadialGradient(
319  {500, 600}, 75, std::move(gradient_colors), std::move(stops),
320  Entity::TileMode::kMirror, {});
321  draw(paint, 0, 300);
322 
323  paint.color_source = ColorSource::MakeImage(
324  texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {},
325  Matrix::MakeTranslation({0, 0}));
326  draw(paint, 300, 0);
327 
328  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
329 }

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

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

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

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

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

Definition at line 499 of file aiks_gradient_unittests.cc.

499  {
500  CanRenderSweepGradient(this, Entity::TileMode::kClamp);
501 }

References impeller::Entity::kClamp.

◆ TEST_P() [79/384]

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

Definition at line 508 of file aiks_gradient_unittests.cc.

508  {
509  CanRenderSweepGradient(this, Entity::TileMode::kDecal);
510 }

References impeller::Entity::kDecal.

◆ TEST_P() [80/384]

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

Definition at line 546 of file aiks_gradient_unittests.cc.

546  {
547  CanRenderSweepGradientManyColors(this, Entity::TileMode::kClamp);
548 }

References impeller::Entity::kClamp.

◆ TEST_P() [81/384]

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

Definition at line 555 of file aiks_gradient_unittests.cc.

555  {
556  CanRenderSweepGradientManyColors(this, Entity::TileMode::kDecal);
557 }

References impeller::Entity::kDecal.

◆ TEST_P() [82/384]

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

Definition at line 552 of file aiks_gradient_unittests.cc.

552  {
553  CanRenderSweepGradientManyColors(this, Entity::TileMode::kMirror);
554 }

References impeller::Entity::kMirror.

◆ TEST_P() [83/384]

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

Definition at line 549 of file aiks_gradient_unittests.cc.

549  {
550  CanRenderSweepGradientManyColors(this, Entity::TileMode::kRepeat);
551 }

References impeller::Entity::kRepeat.

◆ TEST_P() [84/384]

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

Definition at line 505 of file aiks_gradient_unittests.cc.

505  {
506  CanRenderSweepGradient(this, Entity::TileMode::kMirror);
507 }

References impeller::Entity::kMirror.

◆ TEST_P() [85/384]

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

Definition at line 502 of file aiks_gradient_unittests.cc.

502  {
503  CanRenderSweepGradient(this, Entity::TileMode::kRepeat);
504 }

References impeller::Entity::kRepeat.

◆ TEST_P() [86/384]

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

Definition at line 161 of file aiks_gradient_unittests.cc.

161  {
163 }

References CanRenderSweepGradientWithDithering().

◆ TEST_P() [87/384]

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

Definition at line 165 of file aiks_gradient_unittests.cc.

165  {
167 }

References CanRenderSweepGradientWithDithering().

◆ TEST_P() [88/384]

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

Definition at line 751 of file aiks_unittests.cc.

751  {
752  Canvas canvas;
753  canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
754  ASSERT_TRUE(RenderTextInCanvasSkia(
755  GetContext(), canvas, "the quick brown fox jumped over the lazy dog!.?",
756  "Roboto-Regular.ttf"));
757  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
758 }

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

◆ TEST_P() [89/384]

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

Definition at line 760 of file aiks_unittests.cc.

760  {
761  Canvas canvas;
762  canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
763  ASSERT_TRUE(RenderTextInCanvasSTB(
764  GetContext(), canvas, "the quick brown fox jumped over the lazy dog!.?",
765  "Roboto-Regular.ttf"));
766 
767  SetTypographerContext(TypographerContextSTB::Make());
768  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
769 }

References impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::TypographerContextSTB::Make(), and RenderTextInCanvasSTB().

◆ TEST_P() [90/384]

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

Definition at line 863 of file aiks_unittests.cc.

863  {
864  Canvas canvas;
865  canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
866 
867  canvas.Translate({100, 100});
868  canvas.Scale(Vector2{0.5, 0.5});
869 
870  // Blend the layer with the parent pass using kClear to expose the coverage.
871  canvas.SaveLayer({.blend_mode = BlendMode::kClear});
872  ASSERT_TRUE(RenderTextInCanvasSkia(
873  GetContext(), canvas, "the quick brown fox jumped over the lazy dog!.?",
874  "Roboto-Regular.ttf"));
875  canvas.Restore();
876 
877  // Render the text again over the cleared coverage rect.
878  ASSERT_TRUE(RenderTextInCanvasSkia(
879  GetContext(), canvas, "the quick brown fox jumped over the lazy dog!.?",
880  "Roboto-Regular.ttf"));
881 
882  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
883 }

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

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

Definition at line 885 of file aiks_unittests.cc.

885  {
886  Canvas canvas;
887  canvas.Translate({200, 150});
888 
889  // Construct the text blob.
890  auto mapping = flutter::testing::OpenFixtureAsSkData("wtf.otf");
891  ASSERT_NE(mapping, nullptr);
892 
893  Scalar font_size = 80;
894  sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
895  SkFont sk_font(font_mgr->makeFromData(mapping), font_size);
896 
897  Paint text_paint;
898  text_paint.color = Color::Blue().WithAlpha(0.8);
899 
900  struct {
901  Point position;
902  const char* text;
903  } text[] = {{Point(0, 0), "0F0F0F0"},
904  {Point(1, 2), "789"},
905  {Point(1, 3), "456"},
906  {Point(1, 4), "123"},
907  {Point(0, 6), "0F0F0F0"}};
908  for (auto& t : text) {
909  canvas.Save();
910  canvas.Translate(t.position * Point(font_size * 2, font_size * 1.1));
911  {
912  auto blob = SkTextBlob::MakeFromString(t.text, sk_font);
913  ASSERT_NE(blob, nullptr);
914  auto frame = MakeTextFrameFromTextBlobSkia(blob);
915  canvas.DrawTextFrame(frame, Point(), text_paint);
916  }
917  canvas.Restore();
918  }
919 
920  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
921 }

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

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

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

Definition at line 211 of file aiks_unittests.cc.

211  {
212  CanRenderTiledTexture(this, Entity::TileMode::kClamp);
213 }

References impeller::Entity::kClamp.

◆ TEST_P() [94/384]

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

Definition at line 215 of file aiks_unittests.cc.

215  {
216  CanRenderTiledTexture(this, Entity::TileMode::kClamp, /*async_submit=*/true);
217 }

References impeller::Entity::kClamp.

◆ TEST_P() [95/384]

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

Definition at line 231 of file aiks_unittests.cc.

231  {
232  CanRenderTiledTexture(this, Entity::TileMode::kClamp, /*async_submit=*/false,
233  Matrix::MakeTranslation({172.f, 172.f, 0.f}));
234 }

References impeller::Entity::kClamp, and impeller::Matrix::MakeTranslation().

◆ TEST_P() [96/384]

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

Definition at line 227 of file aiks_unittests.cc.

227  {
228  CanRenderTiledTexture(this, Entity::TileMode::kDecal);
229 }

References impeller::Entity::kDecal.

◆ TEST_P() [97/384]

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

Definition at line 223 of file aiks_unittests.cc.

223  {
224  CanRenderTiledTexture(this, Entity::TileMode::kMirror);
225 }

References impeller::Entity::kMirror.

◆ TEST_P() [98/384]

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

Definition at line 219 of file aiks_unittests.cc.

219  {
220  CanRenderTiledTexture(this, Entity::TileMode::kRepeat);
221 }

References impeller::Entity::kRepeat.

◆ TEST_P() [99/384]

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

2560  {
2561  Canvas canvas;
2562  canvas.DrawPaint({.color = Color::Red()});
2563 
2564  // Draw two overlapping subpixel circles.
2565  canvas.SaveLayer({});
2566  canvas.DrawCircle({100, 100}, 0.1, {.color = Color::Yellow()});
2567  canvas.Restore();
2568  canvas.SaveLayer({});
2569  canvas.DrawCircle({100, 100}, 0.1, {.color = Color::Yellow()});
2570  canvas.Restore();
2571 
2572  canvas.DrawPaint({.color = Color::Green()});
2573 
2574  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2575 }

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

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

Definition at line 381 of file aiks_unittests.cc.

381  {
382  Canvas canvas;
383 
384  // Cover the whole canvas with red.
385  canvas.DrawPaint({.color = Color::Red()});
386 
387  canvas.Save();
388 
389  // Append two clips, the second resulting in empty coverage.
390  canvas.ClipPath(
391  PathBuilder{}.AddRect(Rect::MakeXYWH(100, 100, 100, 100)).TakePath());
392  canvas.ClipPath(
393  PathBuilder{}.AddRect(Rect::MakeXYWH(300, 300, 100, 100)).TakePath());
394 
395  // Restore to no clips.
396  canvas.Restore();
397 
398  // Replace the whole canvas with green.
399  canvas.DrawPaint({.color = Color::Green()});
400 
401  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
402 }

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

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

Definition at line 422 of file aiks_unittests.cc.

422  {
423  Canvas canvas;
424 
425  Paint red;
426  red.color = Color::Red();
427 
428  Paint alpha;
429  alpha.color = Color::Red().WithAlpha(0.5);
430 
431  canvas.SaveLayer(alpha);
432 
433  canvas.DrawCircle({125, 125}, 125, red);
434 
435  canvas.Restore();
436 
437  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
438 }

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

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

Definition at line 65 of file aiks_unittests.cc.

65  {
66  Canvas canvas;
67  ASSERT_EQ(canvas.GetSaveCount(), 1u);
68  ASSERT_EQ(canvas.Restore(), false);
69 
70  canvas.Translate(Size{100, 100});
71  canvas.Save();
72  ASSERT_EQ(canvas.GetSaveCount(), 2u);
73  ASSERT_MATRIX_NEAR(canvas.GetCurrentTransform(),
74  Matrix::MakeTranslation({100.0, 100.0, 0.0}));
75  ASSERT_TRUE(canvas.Restore());
76  ASSERT_EQ(canvas.GetSaveCount(), 1u);
77  ASSERT_MATRIX_NEAR(canvas.GetCurrentTransform(),
78  Matrix::MakeTranslation({100.0, 100.0, 0.0}));
79 }

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

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

Definition at line 56 of file aiks_unittests.cc.

56  {
57  Canvas canvas;
58  Matrix identity;
59  ASSERT_MATRIX_NEAR(canvas.GetCurrentTransform(), identity);
60  canvas.Translate(Size{100, 100});
61  ASSERT_MATRIX_NEAR(canvas.GetCurrentTransform(),
62  Matrix::MakeTranslation({100.0, 100.0, 0.0}));
63 }

References ASSERT_MATRIX_NEAR, impeller::Canvas::GetCurrentTransform(), impeller::Matrix::MakeTranslation(), and impeller::Canvas::Translate().

◆ TEST_P() [104/384]

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

Definition at line 3249 of file aiks_unittests.cc.

3249  {
3250  auto capture_context = CaptureContext::MakeAllowlist({"TestDocument"});
3251 
3252  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
3253  Canvas canvas;
3254 
3255  capture_context.Rewind();
3256  auto document = capture_context.GetDocument("TestDocument");
3257 
3258  auto color = document.AddColor("Background color", Color::CornflowerBlue());
3259  canvas.DrawPaint({.color = color});
3260 
3261  ImGui::Begin("TestDocument", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
3262  document.GetElement()->properties.Iterate([](CaptureProperty& property) {
3263  property.Invoke({.color = [](CaptureColorProperty& p) {
3264  ImGui::ColorEdit4(p.label.c_str(), reinterpret_cast<float*>(&p.value));
3265  }});
3266  });
3267  ImGui::End();
3268 
3269  return canvas.EndRecordingAsPicture();
3270  };
3271  OpenPlaygroundHere(callback);
3272 }

References impeller::Color::CornflowerBlue(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), and impeller::CaptureContext::MakeAllowlist().

◆ TEST_P() [105/384]

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

Definition at line 3274 of file aiks_unittests.cc.

3274  {
3275  ASSERT_FALSE(GetContext()->capture.IsActive());
3276 }

◆ TEST_P() [106/384]

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

Definition at line 3374 of file aiks_unittests.cc.

3374  {
3375  Canvas canvas;
3376  Paint white;
3377  white.color = Color::Blue();
3378  canvas.DrawRect(Rect::MakeXYWH(0, 0, 600.0, 600.0), white);
3379 
3380  Paint clear;
3381  clear.blend_mode = BlendMode::kClear;
3382 
3383  canvas.DrawCircle(Point::MakeXY(300.0, 300.0), 200.0, clear);
3384 }

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

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

Definition at line 3356 of file aiks_unittests.cc.

3356  {
3357  Canvas canvas;
3358  Paint white;
3359  white.color = Color::Blue();
3360  canvas.DrawRect(Rect::MakeXYWH(0, 0, 600.0, 600.0), white);
3361 
3362  Paint clear;
3363  clear.blend_mode = BlendMode::kClear;
3364  clear.mask_blur_descriptor = Paint::MaskBlurDescriptor{
3365  .style = FilterContents::BlurStyle::kNormal,
3366  .sigma = Sigma(20),
3367  };
3368 
3369  canvas.DrawCircle(Point::MakeXY(300.0, 300.0), 200.0, clear);
3370 
3371  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3372 }

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

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

Definition at line 2078 of file aiks_unittests.cc.

2078  {
2079  Canvas canvas;
2080  canvas.SaveLayer({}, std::nullopt,
2081  ImageFilter::MakeBlur(Sigma(3), Sigma(3),
2082  FilterContents::BlurStyle::kNormal,
2083  Entity::TileMode::kClamp));
2084  canvas.DrawPaint({.color = Color::Red(), .blend_mode = BlendMode::kSource});
2085  canvas.DrawPaint({.color = Color::CornflowerBlue().WithAlpha(0.75),
2086  .blend_mode = BlendMode::kSourceOver});
2087  canvas.Restore();
2088 
2089  Picture picture = canvas.EndRecordingAsPicture();
2090 
2091  std::optional<Color> actual_color;
2092  bool found_subpass = false;
2093  picture.pass->IterateAllElements([&](EntityPass::Element& element) -> bool {
2094  if (auto subpass = std::get_if<std::unique_ptr<EntityPass>>(&element)) {
2095  actual_color = subpass->get()->GetClearColor();
2096  found_subpass = true;
2097  }
2098  // Fail if the first element isn't a subpass.
2099  return true;
2100  });
2101 
2102  EXPECT_TRUE(found_subpass);
2103  EXPECT_FALSE(actual_color.has_value());
2104 }

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

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

Definition at line 3439 of file aiks_unittests.cc.

3439  {
3440  SetWindowSize({400, 400});
3441  Canvas canvas;
3442  canvas.Scale(GetContentScale());
3443  canvas.DrawRect(Rect::MakeLTRB(200, 200, 300, 300), {.color = Color::Red()});
3444  canvas.SaveLayer({
3445  .image_filter = std::make_shared<MatrixImageFilter>(
3446  Matrix::MakeScale({2, 2, 1}), SamplerDescriptor{}),
3447  });
3448  // Draw a rectangle that would fully cover the parent pass size, but not
3449  // the subpass that it is rendered in.
3450  canvas.DrawRect(Rect::MakeLTRB(0, 0, 400, 400), {.color = Color::Green()});
3451  // Draw a bigger rectangle to force the subpass to be bigger.
3452  canvas.DrawRect(Rect::MakeLTRB(0, 0, 800, 800), {.color = Color::Red()});
3453  canvas.Restore();
3454 
3455  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3456 }

References impeller::Color::Green(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeScale(), impeller::Color::Red(), and impeller::Canvas::Scale().

◆ TEST_P() [110/384]

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

Definition at line 3234 of file aiks_unittests.cc.

3234  {
3235  Canvas canvas;
3236  canvas.Translate(Point(0, -400));
3237  Paint paint;
3238  paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
3239  .style = FilterContents::BlurStyle::kNormal,
3240  .sigma = Radius{120 * 3},
3241  };
3242  paint.color = Color::Red();
3243  PathBuilder builder{};
3244  builder.AddRect(Rect::MakeLTRB(0, 0, 800, 800));
3245  canvas.DrawPath(builder.TakePath(), paint);
3246  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3247 }

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

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

Definition at line 3214 of file aiks_unittests.cc.

3214  {
3215  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
3216  auto point = IMPELLER_PLAYGROUND_POINT(Point(400, 400), 20, Color::Green());
3217 
3218  Canvas canvas;
3219  canvas.Translate(point - Point(400, 400));
3220  Paint paint;
3221  paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
3222  .style = FilterContents::BlurStyle::kNormal,
3223  .sigma = Radius{120 * 3},
3224  };
3225  paint.color = Color::Red();
3226  PathBuilder builder{};
3227  builder.AddRect(Rect::MakeLTRB(0, 0, 800, 800));
3228  canvas.DrawPath(builder.TakePath(), paint);
3229  return canvas.EndRecordingAsPicture();
3230  };
3231  ASSERT_TRUE(OpenPlaygroundHere(callback));
3232 }

References impeller::PathBuilder::AddRect(), impeller::Paint::color, impeller::Canvas::DrawPath(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), IMPELLER_PLAYGROUND_POINT, 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/384]

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

Definition at line 2054 of file aiks_unittests.cc.

2054  {
2055  Canvas canvas(Rect::MakeXYWH(0, 0, 100, 100));
2056  canvas.ClipRect(Rect::MakeXYWH(0, 0, 100, 100));
2057  canvas.ClipRect(Rect::MakeXYWH(-100, -100, 300, 300));
2058  canvas.DrawPaint({.color = Color::Red(), .blend_mode = BlendMode::kSource});
2059  canvas.DrawPaint({.color = Color::CornflowerBlue().WithAlpha(0.75),
2060  .blend_mode = BlendMode::kSourceOver});
2061 
2062  Picture picture = canvas.EndRecordingAsPicture();
2063  auto expected = Color::Red().Blend(Color::CornflowerBlue().WithAlpha(0.75),
2064  BlendMode::kSourceOver);
2065  ASSERT_EQ(picture.pass->GetClearColor(), expected);
2066 
2067  std::shared_ptr<ContextSpy> spy = ContextSpy::Make();
2068  std::shared_ptr<Context> real_context = GetContext();
2069  std::shared_ptr<ContextMock> mock_context = spy->MakeContext(real_context);
2070  AiksContext renderer(mock_context, nullptr);
2071  std::shared_ptr<Image> image = picture.ToImage(renderer, {300, 300});
2072 
2073  ASSERT_EQ(spy->render_passes_.size(), 1llu);
2074  std::shared_ptr<RenderPass> render_pass = spy->render_passes_[0];
2075  ASSERT_EQ(render_pass->GetCommands().size(), 0llu);
2076 }

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

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

Definition at line 404 of file aiks_unittests.cc.

404  {
405  std::array<Color, 5> colors = {Color::White(), Color::Black(),
406  Color::SkyBlue(), Color::Red(),
407  Color::Yellow()};
408  Canvas canvas;
409  Paint paint;
410 
411  canvas.Translate(Vector3(300, 300));
412  for (int i = 0; i < 15; i++) {
413  canvas.Scale(Vector3(0.8, 0.8));
414 
415  paint.color = colors[i % colors.size()];
416  canvas.ClipPath(PathBuilder{}.AddCircle({0, 0}, 300).TakePath());
417  canvas.DrawRect(Rect::MakeXYWH(-300, -300, 600, 600), paint);
418  }
419  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
420 }

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

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

Definition at line 2106 of file aiks_unittests.cc.

2106  {
2107  Canvas canvas;
2108  canvas.DrawPaint(
2109  {.color = Color::Yellow(), .blend_mode = BlendMode::kSource});
2110  canvas.SaveLayer({.blend_mode = BlendMode::kMultiply});
2111  canvas.DrawPaint({.color = Color::CornflowerBlue().WithAlpha(0.75),
2112  .blend_mode = BlendMode::kSourceOver});
2113 
2114  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2115 }

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

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

Definition at line 2117 of file aiks_unittests.cc.

2117  {
2118  // Bug: https://github.com/flutter/flutter/issues/131576
2119  Canvas canvas;
2120  canvas.DrawPaint(
2121  {.color = Color::Yellow(), .blend_mode = BlendMode::kSource});
2122  canvas.SaveLayer({}, {},
2123  ImageFilter::MakeBlur(Sigma(20.0), Sigma(20.0),
2124  FilterContents::BlurStyle::kNormal,
2125  Entity::TileMode::kDecal));
2126  canvas.DrawPaint(
2127  {.color = Color::CornflowerBlue(), .blend_mode = BlendMode::kSourceOver});
2128 
2129  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2130 }

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

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

Definition at line 2147 of file aiks_unittests.cc.

2147  {
2148  Canvas canvas;
2149 
2150  canvas.SaveLayer({
2151  .color_filter =
2152  ColorFilter::MakeMatrix({.array =
2153  {
2154  -1.0, 0, 0, 1.0, 0, //
2155  0, -1.0, 0, 1.0, 0, //
2156  0, 0, -1.0, 1.0, 0, //
2157  1.0, 1.0, 1.0, 1.0, 0 //
2158  }}),
2159  });
2160 
2161  canvas.Translate({500, 300, 0});
2162  canvas.Rotate(Radians(2 * kPi / 3));
2163  canvas.DrawRect(Rect::MakeXYWH(100, 100, 200, 200), {.color = Color::Blue()});
2164 
2165  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2166 }

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

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

1072  {
1073  // Compare with https://fiddle.skia.org/c/@BlendModes
1074 
1075  BlendModeSelection blend_modes = GetBlendModeSelection();
1076 
1077  auto draw_color_wheel = [](Canvas& canvas) {
1078  /// color_wheel_sampler: r=0 -> fuchsia, r=2pi/3 -> yellow, r=4pi/3 ->
1079  /// cyan domain: r >= 0 (because modulo used is non euclidean)
1080  auto color_wheel_sampler = [](Radians r) {
1081  Scalar x = r.radians / k2Pi + 1;
1082 
1083  // https://www.desmos.com/calculator/6nhjelyoaj
1084  auto color_cycle = [](Scalar x) {
1085  Scalar cycle = std::fmod(x, 6.0f);
1086  return std::max(0.0f, std::min(1.0f, 2 - std::abs(2 - cycle)));
1087  };
1088  return Color(color_cycle(6 * x + 1), //
1089  color_cycle(6 * x - 1), //
1090  color_cycle(6 * x - 3), //
1091  1);
1092  };
1093 
1094  Paint paint;
1095  paint.blend_mode = BlendMode::kSourceOver;
1096 
1097  // Draw a fancy color wheel for the backdrop.
1098  // https://www.desmos.com/calculator/xw7kafthwd
1099  const int max_dist = 900;
1100  for (int i = 0; i <= 900; i++) {
1101  Radians r(kPhi / k2Pi * i);
1102  Scalar distance = r.radians / std::powf(4.12, 0.0026 * r.radians);
1103  Scalar normalized_distance = static_cast<Scalar>(i) / max_dist;
1104 
1105  paint.color =
1106  color_wheel_sampler(r).WithAlpha(1.0f - normalized_distance);
1107  Point position(distance * std::sin(r.radians),
1108  -distance * std::cos(r.radians));
1109 
1110  canvas.DrawCircle(position, 9 + normalized_distance * 3, paint);
1111  }
1112  };
1113 
1114  std::shared_ptr<Image> color_wheel_image;
1115  Matrix color_wheel_transform;
1116 
1117  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
1118  // UI state.
1119  static bool cache_the_wheel = true;
1120  static int current_blend_index = 3;
1121  static float dst_alpha = 1;
1122  static float src_alpha = 1;
1123  static Color color0 = Color::Red();
1124  static Color color1 = Color::Green();
1125  static Color color2 = Color::Blue();
1126 
1127  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1128  {
1129  ImGui::Checkbox("Cache the wheel", &cache_the_wheel);
1130  ImGui::ListBox("Blending mode", &current_blend_index,
1131  blend_modes.blend_mode_names.data(),
1132  blend_modes.blend_mode_names.size());
1133  ImGui::SliderFloat("Source alpha", &src_alpha, 0, 1);
1134  ImGui::ColorEdit4("Color A", reinterpret_cast<float*>(&color0));
1135  ImGui::ColorEdit4("Color B", reinterpret_cast<float*>(&color1));
1136  ImGui::ColorEdit4("Color C", reinterpret_cast<float*>(&color2));
1137  ImGui::SliderFloat("Destination alpha", &dst_alpha, 0, 1);
1138  }
1139  ImGui::End();
1140 
1141  static Point content_scale;
1142  Point new_content_scale = GetContentScale();
1143 
1144  if (!cache_the_wheel || new_content_scale != content_scale) {
1145  content_scale = new_content_scale;
1146 
1147  // Render the color wheel to an image.
1148 
1149  Canvas canvas;
1150  canvas.Scale(content_scale);
1151 
1152  canvas.Translate(Vector2(500, 400));
1153  canvas.Scale(Vector2(3, 3));
1154 
1155  draw_color_wheel(canvas);
1156  auto color_wheel_picture = canvas.EndRecordingAsPicture();
1157  auto snapshot = color_wheel_picture.Snapshot(renderer);
1158  if (!snapshot.has_value() || !snapshot->texture) {
1159  return std::nullopt;
1160  }
1161  color_wheel_image = std::make_shared<Image>(snapshot->texture);
1162  color_wheel_transform = snapshot->transform;
1163  }
1164 
1165  Canvas canvas;
1166 
1167  // Blit the color wheel backdrop to the screen with managed alpha.
1168  canvas.SaveLayer({.color = Color::White().WithAlpha(dst_alpha),
1169  .blend_mode = BlendMode::kSource});
1170  {
1171  canvas.DrawPaint({.color = Color::White()});
1172 
1173  canvas.Save();
1174  canvas.Transform(color_wheel_transform);
1175  canvas.DrawImage(color_wheel_image, Point(), Paint());
1176  canvas.Restore();
1177  }
1178  canvas.Restore();
1179 
1180  canvas.Scale(content_scale);
1181  canvas.Translate(Vector2(500, 400));
1182  canvas.Scale(Vector2(3, 3));
1183 
1184  // Draw 3 circles to a subpass and blend it in.
1185  canvas.SaveLayer(
1186  {.color = Color::White().WithAlpha(src_alpha),
1187  .blend_mode = blend_modes.blend_mode_values[current_blend_index]});
1188  {
1189  Paint paint;
1190  paint.blend_mode = BlendMode::kPlus;
1191  const Scalar x = std::sin(k2Pi / 3);
1192  const Scalar y = -std::cos(k2Pi / 3);
1193  paint.color = color0;
1194  canvas.DrawCircle(Point(-x, y) * 45, 65, paint);
1195  paint.color = color1;
1196  canvas.DrawCircle(Point(0, -1) * 45, 65, paint);
1197  paint.color = color2;
1198  canvas.DrawCircle(Point(x, y) * 45, 65, paint);
1199  }
1200  canvas.Restore();
1201 
1202  return canvas.EndRecordingAsPicture();
1203  };
1204 
1205  ASSERT_TRUE(OpenPlaygroundHere(callback));
1206 }

References impeller::Paint::blend_mode, impeller::testing::BlendModeSelection::blend_mode_names, impeller::testing::BlendModeSelection::blend_mode_values, impeller::Color::Blue(), impeller::Paint::color, impeller::Canvas::DrawCircle(), impeller::Canvas::DrawImage(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), GetBlendModeSelection(), impeller::Color::Green(), 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() [118/384]

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

Definition at line 539 of file aiks_unittests.cc.

539  {
540  Canvas canvas;
541 
542  // Render a texture directly.
543  {
544  Paint paint;
545  auto image =
546  std::make_shared<Image>(CreateTextureForFixture("kalimba.jpg"));
547  paint.color = Color::Red();
548 
549  canvas.Save();
550  canvas.Translate({100, 200, 0});
551  canvas.Scale(Vector2{0.5, 0.5});
552  canvas.DrawImage(image, Point::MakeXY(100.0, 100.0), paint);
553  canvas.Restore();
554  }
555 
556  // Render an offscreen rendered texture.
557  {
558  Paint red;
559  red.color = Color::Red();
560  Paint green;
561  green.color = Color::Green();
562  Paint blue;
563  blue.color = Color::Blue();
564 
565  Paint alpha;
566  alpha.color = Color::Red().WithAlpha(0.5);
567 
568  canvas.SaveLayer(alpha);
569 
570  canvas.DrawRect(Rect::MakeXYWH(000, 000, 100, 100), red);
571  canvas.DrawRect(Rect::MakeXYWH(020, 020, 100, 100), green);
572  canvas.DrawRect(Rect::MakeXYWH(040, 040, 100, 100), blue);
573 
574  canvas.Restore();
575  }
576 
577  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
578 }

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

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

Definition at line 1675 of file aiks_unittests.cc.

1675  {
1676  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
1677  Canvas canvas;
1678  canvas.Scale(GetContentScale());
1679 
1680  Paint alpha;
1681  alpha.color = Color::Red().WithAlpha(0.5);
1682 
1683  auto current = Point{25, 25};
1684  const auto offset = Point{25, 25};
1685  const auto size = Size(100, 100);
1686 
1687  auto [b0, b1] = IMPELLER_PLAYGROUND_LINE(Point(40, 40), Point(160, 160), 10,
1688  Color::White(), Color::White());
1689  auto bounds = Rect::MakeLTRB(b0.x, b0.y, b1.x, b1.y);
1690 
1691  canvas.DrawRect(bounds, Paint{.color = Color::Yellow(),
1692  .stroke_width = 5.0f,
1693  .style = Paint::Style::kStroke});
1694 
1695  canvas.SaveLayer(alpha, bounds);
1696 
1697  canvas.DrawRect(Rect::MakeOriginSize(current, size),
1698  Paint{.color = Color::Red()});
1699  canvas.DrawRect(Rect::MakeOriginSize(current += offset, size),
1700  Paint{.color = Color::Green()});
1701  canvas.DrawRect(Rect::MakeOriginSize(current += offset, size),
1702  Paint{.color = Color::Blue()});
1703 
1704  canvas.Restore();
1705 
1706  return canvas.EndRecordingAsPicture();
1707  };
1708 
1709  ASSERT_TRUE(OpenPlaygroundHere(callback));
1710 }

References impeller::Color::Blue(), impeller::Paint::color, impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), IMPELLER_PLAYGROUND_LINE, impeller::Paint::kStroke, impeller::TRect< Scalar >::MakeLTRB(), impeller::TRect< Scalar >::MakeOriginSize(), impeller::Color::Red(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), impeller::Canvas::Scale(), impeller::Color::White(), impeller::Color::WithAlpha(), and impeller::Color::Yellow().

◆ TEST_P() [120/384]

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

Definition at line 980 of file aiks_unittests.cc.

980  {
981  std::vector<Color> colors = {Color{0.9568, 0.2627, 0.2118, 1.0},
982  Color{0.1294, 0.5882, 0.9529, 1.0}};
983  std::vector<Scalar> stops = {0.0, 1.0};
984 
985  Paint paint = {
986  .color_source = ColorSource::MakeLinearGradient(
987  {0, 0}, {100, 100}, std::move(colors), std::move(stops),
988  Entity::TileMode::kRepeat, Matrix::MakeScale(Vector3(0.3, 0.3, 0.3))),
989  .blend_mode = BlendMode::kLighten,
990  };
991 
992  Canvas canvas;
993  canvas.DrawPaint({.color = Color::Blue()});
994  canvas.Scale(Vector2(2, 2));
995  canvas.ClipRect(Rect::MakeLTRB(0, 0, 200, 200));
996  canvas.DrawCircle({100, 100}, 100, paint);
997  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
998 }

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

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

Definition at line 2900 of file aiks_unittests.cc.

2900  {
2901  // Draws the image as four squares stiched together.
2902  auto atlas = CreateTextureForFixture("bay_bridge.jpg");
2903  auto size = atlas->GetSize();
2904  auto image = std::make_shared<Image>(atlas);
2905  // Divide image into four quadrants.
2906  Scalar half_width = size.width / 2;
2907  Scalar half_height = size.height / 2;
2908  std::vector<Rect> texture_coordinates = {
2909  Rect::MakeLTRB(0, 0, half_width, half_height),
2910  Rect::MakeLTRB(half_width, 0, size.width, half_height),
2911  Rect::MakeLTRB(0, half_height, half_width, size.height),
2912  Rect::MakeLTRB(half_width, half_height, size.width, size.height)};
2913  // Position quadrants adjacent to eachother.
2914  std::vector<Matrix> transforms = {
2915  Matrix::MakeTranslation({0, 0, 0}),
2916  Matrix::MakeTranslation({half_width, 0, 0}),
2917  Matrix::MakeTranslation({0, half_height, 0}),
2918  Matrix::MakeTranslation({half_width, half_height, 0})};
2919 
2920  Paint paint;
2921 
2922  Canvas canvas;
2923  canvas.Scale({0.25, 0.25, 1.0});
2924  canvas.DrawAtlas(image, transforms, texture_coordinates, {},
2925  BlendMode::kModulate, {}, std::nullopt, paint);
2926 
2927  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2928 }

References impeller::Canvas::DrawAtlas(), impeller::Canvas::EndRecordingAsPicture(), impeller::kModulate, impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeTranslation(), and impeller::Canvas::Scale().

◆ TEST_P() [122/384]

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

Definition at line 2867 of file aiks_unittests.cc.

2867  {
2868  // Draws the image as four squares stiched together.
2869  auto atlas = CreateTextureForFixture("bay_bridge.jpg");
2870  auto size = atlas->GetSize();
2871  auto image = std::make_shared<Image>(atlas);
2872  // Divide image into four quadrants.
2873  Scalar half_width = size.width / 2;
2874  Scalar half_height = size.height / 2;
2875  std::vector<Rect> texture_coordinates = {
2876  Rect::MakeLTRB(0, 0, half_width, half_height),
2877  Rect::MakeLTRB(half_width, 0, size.width, half_height),
2878  Rect::MakeLTRB(0, half_height, half_width, size.height),
2879  Rect::MakeLTRB(half_width, half_height, size.width, size.height)};
2880  // Position quadrants adjacent to eachother.
2881  std::vector<Matrix> transforms = {
2882  Matrix::MakeTranslation({0, 0, 0}),
2883  Matrix::MakeTranslation({half_width, 0, 0}),
2884  Matrix::MakeTranslation({0, half_height, 0}),
2885  Matrix::MakeTranslation({half_width, half_height, 0})};
2886  std::vector<Color> colors = {Color::Red(), Color::Green(), Color::Blue(),
2887  Color::Yellow()};
2888 
2889  Paint paint;
2890 
2891  Canvas canvas;
2892  canvas.Scale({0.25, 0.25, 1.0});
2893  canvas.DrawAtlas(image, transforms, texture_coordinates, colors,
2894  BlendMode::kModulate, {}, std::nullopt, paint);
2895 
2896  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2897 }

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

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

Definition at line 244 of file aiks_path_unittests.cc.

244  {
245  Canvas canvas;
246  canvas.Scale(GetContentScale());
247  Paint paint;
248  paint.color = Color::Blue();
249  paint.stroke_width = 10;
250 
251  auto draw = [&canvas](Paint& paint) {
252  for (auto cap : {Cap::kButt, Cap::kSquare, Cap::kRound}) {
253  paint.stroke_cap = cap;
254  Point origin = {100, 100};
255  Point p0 = {50, 0};
256  Point p1 = {150, 0};
257  canvas.DrawLine({150, 100}, {250, 100}, paint);
258  for (int d = 15; d < 90; d += 15) {
259  Matrix m = Matrix::MakeRotationZ(Degrees(d));
260  canvas.DrawLine(origin + m * p0, origin + m * p1, paint);
261  }
262  canvas.DrawLine({100, 150}, {100, 250}, paint);
263  canvas.DrawCircle({origin}, 35, paint);
264 
265  canvas.DrawLine({250, 250}, {250, 250}, paint);
266 
267  canvas.Translate({250, 0});
268  }
269  canvas.Translate({-750, 250});
270  };
271 
272  std::vector<Color> colors = {
273  Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0},
274  Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0},
275  Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0},
276  Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0},
277  Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0},
278  Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0},
279  Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}};
280  std::vector<Scalar> stops = {
281  0.0,
282  (1.0 / 6.0) * 1,
283  (1.0 / 6.0) * 2,
284  (1.0 / 6.0) * 3,
285  (1.0 / 6.0) * 4,
286  (1.0 / 6.0) * 5,
287  1.0,
288  };
289 
290  auto texture = CreateTextureForFixture("airplane.jpg",
291  /*enable_mipmapping=*/true);
292 
293  draw(paint);
294 
295  paint.color_source = ColorSource::MakeRadialGradient(
296  {100, 100}, 200, std::move(colors), std::move(stops),
297  Entity::TileMode::kMirror, {});
298  draw(paint);
299 
300  paint.color_source = ColorSource::MakeImage(
301  texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {},
302  Matrix::MakeTranslation({-150, 75}));
303  draw(paint);
304 
305  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
306 }

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

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

Definition at line 1928 of file aiks_unittests.cc.

1928  {
1929  Canvas canvas;
1930  canvas.DrawPaint({.color = Color::Red(), .blend_mode = BlendMode::kSource});
1931  canvas.DrawPaint({.color = Color::CornflowerBlue().WithAlpha(0.75),
1932  .blend_mode = BlendMode::kSourceOver});
1933 
1934  Picture picture = canvas.EndRecordingAsPicture();
1935  auto expected = Color::Red().Blend(Color::CornflowerBlue().WithAlpha(0.75),
1936  BlendMode::kSourceOver);
1937  ASSERT_EQ(picture.pass->GetClearColor(), expected);
1938 
1939  std::shared_ptr<ContextSpy> spy = ContextSpy::Make();
1940  std::shared_ptr<Context> real_context = GetContext();
1941  std::shared_ptr<ContextMock> mock_context = spy->MakeContext(real_context);
1942  AiksContext renderer(mock_context, nullptr);
1943  std::shared_ptr<Image> image = picture.ToImage(renderer, {300, 300});
1944 
1945  ASSERT_EQ(spy->render_passes_.size(), 1llu);
1946  std::shared_ptr<RenderPass> render_pass = spy->render_passes_[0];
1947  ASSERT_EQ(render_pass->GetCommands().size(), 0llu);
1948 }

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

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

Definition at line 2804 of file aiks_unittests.cc.

2804  {
2805  if (!BackendSupportsFragmentProgram()) {
2806  GTEST_SKIP_("This backend doesn't support runtime effects.");
2807  }
2808 
2809  auto runtime_stages = OpenAssetAsRuntimeStage("gradient.frag.iplr");
2810  auto runtime_stage = runtime_stages[RuntimeStageBackend::kMetal];
2811  ASSERT_TRUE(runtime_stage);
2812  ASSERT_TRUE(runtime_stage->IsDirty());
2813 
2814  struct FragUniforms {
2815  Size size;
2816  } frag_uniforms = {.size = Size::MakeWH(400, 400)};
2817  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
2818  uniform_data->resize(sizeof(FragUniforms));
2819  memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
2820 
2821  std::vector<RuntimeEffectContents::TextureInput> texture_inputs;
2822 
2823  Paint paint;
2824  paint.color_source = ColorSource::MakeRuntimeEffect(
2825  runtime_stage, uniform_data, texture_inputs);
2826 
2827  Canvas canvas;
2828  canvas.Save();
2829  canvas.Scale(GetContentScale());
2830  canvas.DrawPaint(paint);
2831  canvas.Restore();
2832 
2833  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2834 }

References impeller::Paint::color_source, impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::kMetal, impeller::ColorSource::MakeRuntimeEffect(), impeller::TSize< Scalar >::MakeWH(), impeller::Canvas::Restore(), impeller::Canvas::Save(), and impeller::Canvas::Scale().

◆ TEST_P() [126/384]

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

Definition at line 963 of file aiks_unittests.cc.

963  {
964  Paint filtered = {
965  .color = Color::Black(),
966  .mask_blur_descriptor =
967  Paint::MaskBlurDescriptor{
968  .style = FilterContents::BlurStyle::kNormal,
969  .sigma = Sigma(60),
970  },
971  };
972 
973  Canvas canvas;
974  canvas.DrawPaint({.color = Color::White()});
975  canvas.DrawCircle({300, 300}, 200, filtered);
976  canvas.DrawPaint({.color = Color::Green(), .blend_mode = BlendMode::kScreen});
977  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
978 }

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

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

Definition at line 3075 of file aiks_unittests.cc.

3075  {
3076  Canvas subcanvas;
3077  subcanvas.ClipRRect(Rect::MakeLTRB(100, 100, 400, 400), {15, 15});
3078  subcanvas.DrawPaint({.color = Color::Red()});
3079  auto picture = subcanvas.EndRecordingAsPicture();
3080 
3081  Canvas canvas;
3082  canvas.DrawPaint({.color = Color::CornflowerBlue()});
3083 
3084  // Draw a red RRect via DrawPicture.
3085  canvas.DrawPicture(picture);
3086 
3087  // Draw over the picture with a larger green rectangle, completely covering it
3088  // up.
3089  canvas.ClipRRect(Rect::MakeLTRB(100, 100, 400, 400).Expand(20), {15, 15});
3090  canvas.DrawPaint({.color = Color::Green()});
3091 
3092  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3093 }

References impeller::Canvas::ClipRRect(), impeller::Color::CornflowerBlue(), impeller::Canvas::DrawPaint(), impeller::Canvas::DrawPicture(), impeller::Canvas::EndRecordingAsPicture(), impeller::TRect< T >::Expand(), impeller::Color::Green(), impeller::TRect< Scalar >::MakeLTRB(), and impeller::Color::Red().

◆ TEST_P() [128/384]

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

Definition at line 3046 of file aiks_unittests.cc.

3046  {
3047  Canvas subcanvas;
3048  ASSERT_TRUE(RenderTextInCanvasSkia(
3049  GetContext(), subcanvas,
3050  "the quick brown fox jumped over the lazy dog!.?", "Roboto-Regular.ttf"));
3051  subcanvas.Translate({0, 10});
3052  subcanvas.Scale(Vector2(3, 3));
3053  ASSERT_TRUE(RenderTextInCanvasSkia(
3054  GetContext(), subcanvas,
3055  "the quick brown fox jumped over the very big lazy dog!.?",
3056  "Roboto-Regular.ttf"));
3057  auto picture = subcanvas.EndRecordingAsPicture();
3058 
3059  Canvas canvas;
3060  canvas.Scale(Vector2(.2, .2));
3061  canvas.Save();
3062  canvas.Translate({200, 200});
3063  canvas.Scale(Vector2(3.5, 3.5)); // The text must not be blurry after this.
3064  canvas.DrawPicture(picture);
3065  canvas.Restore();
3066 
3067  canvas.Scale(Vector2(1.5, 1.5));
3068  ASSERT_TRUE(RenderTextInCanvasSkia(
3069  GetContext(), canvas,
3070  "the quick brown fox jumped over the smaller lazy dog!.?",
3071  "Roboto-Regular.ttf"));
3072  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3073 }

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

◆ TEST_P() [129/384]

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

Definition at line 1974 of file aiks_unittests.cc.

1974  {
1975  Canvas canvas;
1976  canvas.DrawRect(Rect::MakeXYWH(0, 0, 300, 300),
1977  {.color = Color::Red(), .blend_mode = BlendMode::kSource});
1978  canvas.DrawRect(Rect::MakeXYWH(0, 0, 300, 300),
1979  {.color = Color::CornflowerBlue().WithAlpha(0.75),
1980  .blend_mode = BlendMode::kSourceOver});
1981 
1982  std::shared_ptr<ContextSpy> spy = ContextSpy::Make();
1983  Picture picture = canvas.EndRecordingAsPicture();
1984  std::shared_ptr<Context> real_context = GetContext();
1985  std::shared_ptr<ContextMock> mock_context = spy->MakeContext(real_context);
1986  AiksContext renderer(mock_context, nullptr);
1987  std::shared_ptr<Image> image = picture.ToImage(renderer, {300, 300});
1988 
1989  ASSERT_EQ(spy->render_passes_.size(), 1llu);
1990  std::shared_ptr<RenderPass> render_pass = spy->render_passes_[0];
1991  ASSERT_EQ(render_pass->GetCommands().size(), 0llu);
1992 }

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

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

Definition at line 2034 of file aiks_unittests.cc.

2034  {
2035  Canvas canvas;
2036  canvas.DrawRect(Rect::MakeXYWH(0, 0, 300, 300),
2037  {.color = Color::Red(), .blend_mode = BlendMode::kSource});
2038  canvas.DrawRect(Rect::MakeXYWH(0, 0, 300, 300),
2039  {.color = Color::CornflowerBlue().WithAlpha(0.75),
2040  .blend_mode = BlendMode::kSourceOver});
2041 
2042  std::shared_ptr<ContextSpy> spy = ContextSpy::Make();
2043  Picture picture = canvas.EndRecordingAsPicture();
2044  std::shared_ptr<Context> real_context = GetContext();
2045  std::shared_ptr<ContextMock> mock_context = spy->MakeContext(real_context);
2046  AiksContext renderer(mock_context, nullptr);
2047  std::shared_ptr<Image> image = picture.ToImage(renderer, {301, 301});
2048 
2049  ASSERT_EQ(spy->render_passes_.size(), 1llu);
2050  std::shared_ptr<RenderPass> render_pass = spy->render_passes_[0];
2051  ASSERT_EQ(render_pass->GetCommands().size(), 2llu);
2052 }

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

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

Definition at line 2014 of file aiks_unittests.cc.

2014  {
2015  Canvas canvas;
2016  canvas.Translate(Vector3(150.0, 150.0, 0.0));
2017  canvas.Rotate(Degrees(45.0));
2018  canvas.Translate(Vector3(-150.0, -150.0, 0.0));
2019  canvas.DrawRect(Rect::MakeXYWH(0, 0, 300, 300),
2020  {.color = Color::Red(), .blend_mode = BlendMode::kSource});
2021 
2022  std::shared_ptr<ContextSpy> spy = ContextSpy::Make();
2023  Picture picture = canvas.EndRecordingAsPicture();
2024  std::shared_ptr<Context> real_context = GetContext();
2025  std::shared_ptr<ContextMock> mock_context = spy->MakeContext(real_context);
2026  AiksContext renderer(mock_context, nullptr);
2027  std::shared_ptr<Image> image = picture.ToImage(renderer, {300, 300});
2028 
2029  ASSERT_EQ(spy->render_passes_.size(), 1llu);
2030  std::shared_ptr<RenderPass> render_pass = spy->render_passes_[0];
2031  ASSERT_EQ(render_pass->GetCommands().size(), 1llu);
2032 }

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

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

Definition at line 1994 of file aiks_unittests.cc.

1994  {
1995  Canvas canvas;
1996  canvas.DrawRRect(Rect::MakeXYWH(0, 0, 300, 300), {5.0, 5.0},
1997  {.color = Color::Red(), .blend_mode = BlendMode::kSource});
1998  canvas.DrawRRect(Rect::MakeXYWH(0, 0, 300, 300), {5.0, 5.0},
1999  {.color = Color::CornflowerBlue().WithAlpha(0.75),
2000  .blend_mode = BlendMode::kSourceOver});
2001 
2002  std::shared_ptr<ContextSpy> spy = ContextSpy::Make();
2003  Picture picture = canvas.EndRecordingAsPicture();
2004  std::shared_ptr<Context> real_context = GetContext();
2005  std::shared_ptr<ContextMock> mock_context = spy->MakeContext(real_context);
2006  AiksContext renderer(mock_context, nullptr);
2007  std::shared_ptr<Image> image = picture.ToImage(renderer, {300, 300});
2008 
2009  ASSERT_EQ(spy->render_passes_.size(), 1llu);
2010  std::shared_ptr<RenderPass> render_pass = spy->render_passes_[0];
2011  ASSERT_EQ(render_pass->GetCommands().size(), 2llu);
2012 }

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

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

Definition at line 308 of file aiks_path_unittests.cc.

308  {
309  Canvas canvas;
310  Paint paint;
311  paint.color = Color::Red();
312  paint.style = Paint::Style::kStroke;
313  paint.stroke_width = 10;
314 
315  canvas.Translate({100, 100});
316  canvas.DrawPath(
317  PathBuilder{}.AddRect(Rect::MakeSize(Size{100, 100})).TakePath(),
318  {paint});
319 
320  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
321 }

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

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

Definition at line 323 of file aiks_path_unittests.cc.

323  {
324  Canvas canvas;
325  Paint paint;
326  paint.color = Color::Red();
327  paint.style = Paint::Style::kStroke;
328  paint.stroke_width = 10;
329  paint.stroke_join = Join::kBevel;
330 
331  canvas.Translate({100, 100});
332  canvas.DrawPath(
333  PathBuilder{}.AddRect(Rect::MakeSize(Size{100, 100})).TakePath(),
334  {paint});
335 
336  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
337 }

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

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

Definition at line 3157 of file aiks_unittests.cc.

3157  {
3158  Canvas canvas;
3159  // clang-format off
3160  canvas.Transform(Matrix(
3161  2.000000, 0.000000, 0.000000, 0.000000,
3162  1.445767, 2.637070, -0.507928, 0.001524,
3163  -2.451887, -0.534662, 0.861399, -0.002584,
3164  1063.481934, 1025.951416, -48.300270, 1.144901
3165  ));
3166  // clang-format on
3167 
3168  ASSERT_TRUE(RenderTextInCanvasSkia(GetContext(), canvas, "Hello world",
3169  "Roboto-Regular.ttf"));
3170 
3171  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3172 }

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

◆ TEST_P() [136/384]

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

Definition at line 3174 of file aiks_unittests.cc.

3174  {
3175  Canvas canvas;
3176  Paint save_paint;
3177  canvas.SaveLayer(save_paint);
3178  // clang-format off
3179  canvas.Transform(Matrix(
3180  2.000000, 0.000000, 0.000000, 0.000000,
3181  1.445767, 2.637070, -0.507928, 0.001524,
3182  -2.451887, -0.534662, 0.861399, -0.002584,
3183  1063.481934, 1025.951416, -48.300270, 1.144901
3184  ));
3185  // clang-format on
3186 
3187  ASSERT_TRUE(RenderTextInCanvasSkia(GetContext(), canvas, "Hello world",
3188  "Roboto-Regular.ttf"));
3189 }

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

◆ TEST_P() [137/384]

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

Definition at line 3474 of file aiks_unittests.cc.

3474  {
3475  Canvas canvas;
3476  canvas.Scale(GetContentScale());
3477  canvas.DrawPaint(Paint{.color = Color::Red()});
3478  canvas.ClipRect(Rect::MakeXYWH(100, 100, 200, 200));
3479  canvas.SaveLayer(Paint{.color = Color::Blue()});
3480  canvas.Restore();
3481  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3482 }

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

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

Definition at line 3484 of file aiks_unittests.cc.

3484  {
3485  Canvas canvas;
3486  canvas.Scale(GetContentScale());
3487  auto image = std::make_shared<Image>(CreateTextureForFixture("airplane.jpg"));
3488  canvas.DrawImage(image, {10, 10}, {});
3489  canvas.ClipRect(Rect::MakeXYWH(100, 100, 200, 200));
3490  canvas.SaveLayer(Paint{.blend_mode = BlendMode::kClear});
3491  canvas.Restore();
3492  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3493 }

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

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

Definition at line 1247 of file aiks_unittests.cc.

1247  {
1248  Canvas canvas;
1249  canvas.Scale(GetContentScale());
1250  Paint paint;
1251  const int color_count = 3;
1252  Color colors[color_count] = {
1253  Color::Blue(),
1254  Color::Green(),
1255  Color::Crimson(),
1256  };
1257 
1258  paint.color = Color::White();
1259  canvas.DrawPaint(paint);
1260 
1261  int c_index = 0;
1262  int radius = 600;
1263  while (radius > 0) {
1264  paint.color = colors[(c_index++) % color_count];
1265  canvas.DrawCircle({10, 10}, radius, paint);
1266  if (radius > 30) {
1267  radius -= 10;
1268  } else {
1269  radius -= 2;
1270  }
1271  }
1272 
1273  std::vector<Color> gradient_colors = {
1274  Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0},
1275  Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0},
1276  Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0},
1277  Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0},
1278  Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0},
1279  Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0},
1280  Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}};
1281  std::vector<Scalar> stops = {
1282  0.0,
1283  (1.0 / 6.0) * 1,
1284  (1.0 / 6.0) * 2,
1285  (1.0 / 6.0) * 3,
1286  (1.0 / 6.0) * 4,
1287  (1.0 / 6.0) * 5,
1288  1.0,
1289  };
1290  auto texture = CreateTextureForFixture("airplane.jpg",
1291  /*enable_mipmapping=*/true);
1292 
1293  paint.color_source = ColorSource::MakeRadialGradient(
1294  {500, 600}, 75, std::move(gradient_colors), std::move(stops),
1295  Entity::TileMode::kMirror, {});
1296  canvas.DrawCircle({500, 600}, 100, paint);
1297 
1298  paint.color_source = ColorSource::MakeImage(
1299  texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {},
1300  Matrix::MakeTranslation({700, 200}));
1301  canvas.DrawCircle({800, 300}, 100, paint);
1302 
1303  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1304 }

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

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

Definition at line 1370 of file aiks_unittests.cc.

1370  {
1371  Canvas canvas;
1372  canvas.Scale(GetContentScale());
1373  Paint paint;
1374  const int color_count = 3;
1375  Color colors[color_count] = {
1376  Color::Blue(),
1377  Color::Green(),
1378  Color::Crimson(),
1379  };
1380 
1381  paint.color = Color::White();
1382  canvas.DrawPaint(paint);
1383 
1384  int c_index = 0;
1385  int long_radius = 600;
1386  int short_radius = 600;
1387  while (long_radius > 0 && short_radius > 0) {
1388  paint.color = colors[(c_index++) % color_count];
1389  canvas.DrawOval(Rect::MakeXYWH(10 - long_radius, 10 - short_radius,
1390  long_radius * 2, short_radius * 2),
1391  paint);
1392  canvas.DrawOval(Rect::MakeXYWH(1000 - short_radius, 750 - long_radius,
1393  short_radius * 2, long_radius * 2),
1394  paint);
1395  if (short_radius > 30) {
1396  short_radius -= 10;
1397  long_radius -= 5;
1398  } else {
1399  short_radius -= 2;
1400  long_radius -= 1;
1401  }
1402  }
1403 
1404  std::vector<Color> gradient_colors = {
1405  Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0},
1406  Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0},
1407  Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0},
1408  Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0},
1409  Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0},
1410  Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0},
1411  Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}};
1412  std::vector<Scalar> stops = {
1413  0.0,
1414  (1.0 / 6.0) * 1,
1415  (1.0 / 6.0) * 2,
1416  (1.0 / 6.0) * 3,
1417  (1.0 / 6.0) * 4,
1418  (1.0 / 6.0) * 5,
1419  1.0,
1420  };
1421  auto texture = CreateTextureForFixture("airplane.jpg",
1422  /*enable_mipmapping=*/true);
1423 
1424  paint.color = Color::White().WithAlpha(0.5);
1425 
1426  paint.color_source = ColorSource::MakeRadialGradient(
1427  {300, 650}, 75, std::move(gradient_colors), std::move(stops),
1428  Entity::TileMode::kMirror, {});
1429  canvas.DrawOval(Rect::MakeXYWH(200, 625, 200, 50), paint);
1430  canvas.DrawOval(Rect::MakeXYWH(275, 550, 50, 200), paint);
1431 
1432  paint.color_source = ColorSource::MakeImage(
1433  texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {},
1434  Matrix::MakeTranslation({610, 15}));
1435  canvas.DrawOval(Rect::MakeXYWH(610, 90, 200, 50), paint);
1436  canvas.DrawOval(Rect::MakeXYWH(685, 15, 50, 200), paint);
1437 
1438  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1439 }

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

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

Definition at line 1585 of file aiks_unittests.cc.

1585  {
1586  Canvas canvas;
1587  canvas.Scale(GetContentScale());
1588  Paint paint;
1589  const int color_count = 3;
1590  Color colors[color_count] = {
1591  Color::Blue(),
1592  Color::Green(),
1593  Color::Crimson(),
1594  };
1595 
1596  paint.color = Color::White();
1597  canvas.DrawPaint(paint);
1598 
1599  auto draw_rrect_as_path = [&canvas](const Rect& rect, const Size& radii,
1600  const Paint& paint) {
1601  PathBuilder builder = PathBuilder();
1602  builder.AddRoundedRect(rect, radii);
1603  canvas.DrawPath(builder.TakePath(), paint);
1604  };
1605 
1606  int c_index = 0;
1607  for (int i = 0; i < 4; i++) {
1608  for (int j = 0; j < 4; j++) {
1609  paint.color = colors[(c_index++) % color_count];
1610  draw_rrect_as_path(Rect::MakeXYWH(i * 100 + 10, j * 100 + 20, 80, 80),
1611  Size(i * 5 + 10, j * 5 + 10), paint);
1612  }
1613  }
1614  paint.color = colors[(c_index++) % color_count];
1615  draw_rrect_as_path(Rect::MakeXYWH(10, 420, 380, 80), Size(40, 40), paint);
1616  paint.color = colors[(c_index++) % color_count];
1617  draw_rrect_as_path(Rect::MakeXYWH(410, 20, 80, 380), Size(40, 40), paint);
1618 
1619  std::vector<Color> gradient_colors = {
1620  Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0},
1621  Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0},
1622  Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0},
1623  Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0},
1624  Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0},
1625  Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0},
1626  Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}};
1627  std::vector<Scalar> stops = {
1628  0.0,
1629  (1.0 / 6.0) * 1,
1630  (1.0 / 6.0) * 2,
1631  (1.0 / 6.0) * 3,
1632  (1.0 / 6.0) * 4,
1633  (1.0 / 6.0) * 5,
1634  1.0,
1635  };
1636  auto texture = CreateTextureForFixture("airplane.jpg",
1637  /*enable_mipmapping=*/true);
1638 
1639  paint.color = Color::White().WithAlpha(0.1);
1640  paint.color_source = ColorSource::MakeRadialGradient(
1641  {550, 550}, 75, gradient_colors, stops, Entity::TileMode::kMirror, {});
1642  for (int i = 1; i <= 10; i++) {
1643  int j = 11 - i;
1644  draw_rrect_as_path(Rect::MakeLTRB(550 - i * 20, 550 - j * 20, //
1645  550 + i * 20, 550 + j * 20),
1646  Size(i * 10, j * 10), paint);
1647  }
1648  paint.color = Color::White().WithAlpha(0.5);
1649  paint.color_source = ColorSource::MakeRadialGradient(
1650  {200, 650}, 75, std::move(gradient_colors), std::move(stops),
1651  Entity::TileMode::kMirror, {});
1652  draw_rrect_as_path(Rect::MakeLTRB(100, 610, 300, 690), Size(40, 40), paint);
1653  draw_rrect_as_path(Rect::MakeLTRB(160, 550, 240, 750), Size(40, 40), paint);
1654 
1655  paint.color = Color::White().WithAlpha(0.1);
1656  paint.color_source = ColorSource::MakeImage(
1657  texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {},
1658  Matrix::MakeTranslation({520, 20}));
1659  for (int i = 1; i <= 10; i++) {
1660  int j = 11 - i;
1661  draw_rrect_as_path(Rect::MakeLTRB(720 - i * 20, 220 - j * 20, //
1662  720 + i * 20, 220 + j * 20),
1663  Size(i * 10, j * 10), paint);
1664  }
1665  paint.color = Color::White().WithAlpha(0.5);
1666  paint.color_source = ColorSource::MakeImage(
1667  texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {},
1668  Matrix::MakeTranslation({800, 300}));
1669  draw_rrect_as_path(Rect::MakeLTRB(800, 410, 1000, 490), Size(40, 40), paint);
1670  draw_rrect_as_path(Rect::MakeLTRB(860, 350, 940, 550), Size(40, 40), paint);
1671 
1672  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1673 }

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

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

Definition at line 1441 of file aiks_unittests.cc.

1441  {
1442  Canvas canvas;
1443  canvas.Scale(GetContentScale());
1444  Paint paint;
1445  const int color_count = 3;
1446  Color colors[color_count] = {
1447  Color::Blue(),
1448  Color::Green(),
1449  Color::Crimson(),
1450  };
1451 
1452  paint.color = Color::White();
1453  canvas.DrawPaint(paint);
1454 
1455  int c_index = 0;
1456  for (int i = 0; i < 4; i++) {
1457  for (int j = 0; j < 4; j++) {
1458  paint.color = colors[(c_index++) % color_count];
1459  canvas.DrawRRect(Rect::MakeXYWH(i * 100 + 10, j * 100 + 20, 80, 80),
1460  Size(i * 5 + 10, j * 5 + 10), paint);
1461  }
1462  }
1463  paint.color = colors[(c_index++) % color_count];
1464  canvas.DrawRRect(Rect::MakeXYWH(10, 420, 380, 80), Size(40, 40), paint);
1465  paint.color = colors[(c_index++) % color_count];
1466  canvas.DrawRRect(Rect::MakeXYWH(410, 20, 80, 380), Size(40, 40), paint);
1467 
1468  std::vector<Color> gradient_colors = {
1469  Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0},
1470  Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0},
1471  Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0},
1472  Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0},
1473  Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0},
1474  Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0},
1475  Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}};
1476  std::vector<Scalar> stops = {
1477  0.0,
1478  (1.0 / 6.0) * 1,
1479  (1.0 / 6.0) * 2,
1480  (1.0 / 6.0) * 3,
1481  (1.0 / 6.0) * 4,
1482  (1.0 / 6.0) * 5,
1483  1.0,
1484  };
1485  auto texture = CreateTextureForFixture("airplane.jpg",
1486  /*enable_mipmapping=*/true);
1487 
1488  paint.color = Color::White().WithAlpha(0.1);
1489  paint.color_source = ColorSource::MakeRadialGradient(
1490  {550, 550}, 75, gradient_colors, stops, Entity::TileMode::kMirror, {});
1491  for (int i = 1; i <= 10; i++) {
1492  int j = 11 - i;
1493  canvas.DrawRRect(Rect::MakeLTRB(550 - i * 20, 550 - j * 20, //
1494  550 + i * 20, 550 + j * 20),
1495  Size(i * 10, j * 10), paint);
1496  }
1497  paint.color = Color::White().WithAlpha(0.5);
1498  paint.color_source = ColorSource::MakeRadialGradient(
1499  {200, 650}, 75, std::move(gradient_colors), std::move(stops),
1500  Entity::TileMode::kMirror, {});
1501  canvas.DrawRRect(Rect::MakeLTRB(100, 610, 300, 690), Size(40, 40), paint);
1502  canvas.DrawRRect(Rect::MakeLTRB(160, 550, 240, 750), Size(40, 40), paint);
1503 
1504  paint.color = Color::White().WithAlpha(0.1);
1505  paint.color_source = ColorSource::MakeImage(
1506  texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {},
1507  Matrix::MakeTranslation({520, 20}));
1508  for (int i = 1; i <= 10; i++) {
1509  int j = 11 - i;
1510  canvas.DrawRRect(Rect::MakeLTRB(720 - i * 20, 220 - j * 20, //
1511  720 + i * 20, 220 + j * 20),
1512  Size(i * 10, j * 10), paint);
1513  }
1514  paint.color = Color::White().WithAlpha(0.5);
1515  paint.color_source = ColorSource::MakeImage(
1516  texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {},
1517  Matrix::MakeTranslation({800, 300}));
1518  canvas.DrawRRect(Rect::MakeLTRB(800, 410, 1000, 490), Size(40, 40), paint);
1519  canvas.DrawRRect(Rect::MakeLTRB(860, 350, 940, 550), Size(40, 40), paint);
1520 
1521  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1522 }

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

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

Definition at line 2132 of file aiks_unittests.cc.

2132  {
2133  Canvas canvas;
2134 
2135  canvas.SaveLayer({
2136  .color_filter =
2137  ColorFilter::MakeBlend(BlendMode::kColorDodge, Color::Red()),
2138  });
2139 
2140  canvas.Translate({500, 300, 0});
2141  canvas.Rotate(Radians(2 * kPi / 3));
2142  canvas.DrawRect(Rect::MakeXYWH(100, 100, 200, 200), {.color = Color::Blue()});
2143 
2144  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2145 }

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

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

Definition at line 3581 of file aiks_unittests.cc.

3581  {
3582  Canvas canvas;
3583 
3584  canvas.Scale(GetContentScale());
3585  std::shared_ptr<Texture> boston = CreateTextureForFixture("boston.jpg");
3586  canvas.DrawImageRect(
3587  std::make_shared<Image>(boston),
3588  Rect::MakeXYWH(0, 0, boston->GetSize().width, boston->GetSize().height),
3589  Rect::MakeLTRB(0, 0, GetWindowSize().width, 100), Paint{});
3590  canvas.DrawRRect(Rect::MakeLTRB(0, 110, GetWindowSize().width, 210),
3591  Size(10, 10), Paint{.color = Color::Magenta()});
3592  canvas.ClipRect(Rect::MakeLTRB(0, 50, GetWindowSize().width, 150));
3593  canvas.SaveLayer({.blend_mode = BlendMode::kSource}, std::nullopt,
3594  ImageFilter::MakeBlur(Sigma(20.0), Sigma(20.0),
3595  FilterContents::BlurStyle::kNormal,
3596  Entity::TileMode::kClamp));
3597  canvas.Restore();
3598  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3599 }

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

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

Definition at line 3563 of file aiks_unittests.cc.

3563  {
3564  Canvas canvas;
3565 
3566  canvas.Scale(GetContentScale());
3567  canvas.DrawRRect(Rect::MakeLTRB(0, 0, GetWindowSize().width, 100),
3568  Size(10, 10), Paint{.color = Color::LimeGreen()});
3569  canvas.DrawRRect(Rect::MakeLTRB(0, 110, GetWindowSize().width, 210),
3570  Size(10, 10), Paint{.color = Color::Magenta()});
3571  canvas.ClipRect(Rect::MakeLTRB(100, 0, 200, GetWindowSize().height));
3572  canvas.SaveLayer({.blend_mode = BlendMode::kSource}, std::nullopt,
3573  ImageFilter::MakeBlur(Sigma(20.0), Sigma(20.0),
3574  FilterContents::BlurStyle::kNormal,
3575  Entity::TileMode::kClamp));
3576  canvas.Restore();
3577 
3578  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3579 }

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

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

Definition at line 3650 of file aiks_unittests.cc.

3650  {
3651  Canvas canvas;
3652 
3653  canvas.Scale(GetContentScale());
3654  canvas.Scale({0.5, 0.5, 1.0});
3655  std::shared_ptr<Texture> boston = CreateTextureForFixture("boston.jpg");
3656  canvas.DrawImage(std::make_shared<Image>(boston), Point(100, 100), Paint{});
3657  canvas.SaveLayer({.blend_mode = BlendMode::kSource}, std::nullopt,
3658  ImageFilter::MakeBlur(Sigma(50.0), Sigma(0.0),
3659  FilterContents::BlurStyle::kNormal,
3660  Entity::TileMode::kClamp));
3661  canvas.Restore();
3662  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3663 }

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

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

Definition at line 3669 of file aiks_unittests.cc.

3669  {
3670  Canvas canvas;
3671  std::shared_ptr<Texture> boston = CreateTextureForFixture("boston.jpg");
3672  Rect bounds =
3673  Rect::MakeXYWH(0, 0, boston->GetSize().width, boston->GetSize().height);
3674  Vector2 image_center = Vector2(bounds.GetSize() / 2);
3675  Paint paint = {.image_filter =
3676  ImageFilter::MakeBlur(Sigma(20.0), Sigma(20.0),
3677  FilterContents::BlurStyle::kNormal,
3678  Entity::TileMode::kDecal)};
3679  Vector2 clip_size = {150, 75};
3680  Vector2 center = Vector2(1024, 768) / 2;
3681  canvas.Scale(GetContentScale());
3682  canvas.ClipRect(
3683  Rect::MakeLTRB(center.x, center.y, center.x, center.y).Expand(clip_size));
3684  canvas.Translate({center.x, center.y, 0});
3685  canvas.Scale({0.6, 0.6, 1});
3686  canvas.Rotate(Degrees(25));
3687 
3688  canvas.DrawImageRect(std::make_shared<Image>(boston), /*source=*/bounds,
3689  /*dest=*/bounds.Shift(-image_center), paint);
3690 
3691  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3692 }

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

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

Definition at line 3718 of file aiks_unittests.cc.

3718  {
3719  std::shared_ptr<Texture> boston = CreateTextureForFixture("boston.jpg");
3720 
3721  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
3722  const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
3723  const Entity::TileMode tile_modes[] = {
3724  Entity::TileMode::kClamp, Entity::TileMode::kRepeat,
3725  Entity::TileMode::kMirror, Entity::TileMode::kDecal};
3726 
3727  static float rotation = 0;
3728  static float scale = 0.6;
3729  static int selected_tile_mode = 3;
3730 
3731  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
3732  {
3733  ImGui::SliderFloat("Rotation (degrees)", &rotation, -180, 180);
3734  ImGui::SliderFloat("Scale", &scale, 0, 2.0);
3735  ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
3736  sizeof(tile_mode_names) / sizeof(char*));
3737  }
3738  ImGui::End();
3739 
3740  Canvas canvas;
3741  Rect bounds =
3742  Rect::MakeXYWH(0, 0, boston->GetSize().width, boston->GetSize().height);
3743  Vector2 image_center = Vector2(bounds.GetSize() / 2);
3744  Paint paint = {.image_filter =
3745  ImageFilter::MakeBlur(Sigma(20.0), Sigma(20.0),
3746  FilterContents::BlurStyle::kNormal,
3747  tile_modes[selected_tile_mode])};
3748  auto [handle_a, handle_b] = IMPELLER_PLAYGROUND_LINE(
3749  Point(362, 309), Point(662, 459), 20, Color::Red(), Color::Red());
3750  Vector2 center = Vector2(1024, 768) / 2;
3751  canvas.Scale(GetContentScale());
3752  canvas.ClipRect(
3753  Rect::MakeLTRB(handle_a.x, handle_a.y, handle_b.x, handle_b.y));
3754  canvas.Translate({center.x, center.y, 0});
3755  canvas.Scale({scale, scale, 1});
3756  canvas.Rotate(Degrees(rotation));
3757 
3758  canvas.DrawImageRect(std::make_shared<Image>(boston), /*source=*/bounds,
3759  /*dest=*/bounds.Shift(-image_center), paint);
3760  return canvas.EndRecordingAsPicture();
3761  };
3762 
3763  ASSERT_TRUE(OpenPlaygroundHere(callback));
3764 }

References impeller::Canvas::ClipRect(), impeller::Canvas::DrawImageRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::TRect< T >::GetSize(), impeller::Paint::image_filter, IMPELLER_PLAYGROUND_LINE, 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(), impeller::TRect< T >::Shift(), impeller::Canvas::Translate(), impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ TEST_P() [149/384]

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

Definition at line 3694 of file aiks_unittests.cc.

3694  {
3695  Canvas canvas;
3696  std::shared_ptr<Texture> boston = CreateTextureForFixture("boston.jpg");
3697  Rect bounds =
3698  Rect::MakeXYWH(0, 0, boston->GetSize().width, boston->GetSize().height);
3699  Vector2 image_center = Vector2(bounds.GetSize() / 2);
3700  Paint paint = {.image_filter =
3701  ImageFilter::MakeBlur(Sigma(20.0), Sigma(20.0),
3702  FilterContents::BlurStyle::kNormal,
3703  Entity::TileMode::kDecal)};
3704  Vector2 clip_size = {150, 75};
3705  Vector2 center = Vector2(1024, 768) / 2;
3706  canvas.Scale(GetContentScale());
3707  canvas.ClipRect(
3708  Rect::MakeLTRB(center.x, center.y, center.x, center.y).Expand(clip_size));
3709  canvas.Translate({center.x, center.y, 0});
3710  canvas.Scale({0.6, 0.6, 1});
3711 
3712  canvas.DrawImageRect(std::make_shared<Image>(boston), /*source=*/bounds,
3713  /*dest=*/bounds.Shift(-image_center), paint);
3714 
3715  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3716 }

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

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

Definition at line 3605 of file aiks_unittests.cc.

3605  {
3606  if (GetParam() != PlaygroundBackend::kMetal) {
3607  GTEST_SKIP_(
3608  "This backend doesn't yet support setting device capabilities.");
3609  }
3610  if (!WillRenderSomething()) {
3611  // Sometimes these tests are run without playgrounds enabled which is
3612  // pointless for this test since we are asserting that
3613  // `SupportsDecalSamplerAddressMode` is called.
3614  GTEST_SKIP_("This test requires playgrounds.");
3615  }
3616 
3617  std::shared_ptr<const Capabilities> old_capabilities =
3618  GetContext()->GetCapabilities();
3619  auto mock_capabilities = std::make_shared<MockCapabilities>();
3620  EXPECT_CALL(*mock_capabilities, SupportsDecalSamplerAddressMode())
3621  .Times(::testing::AtLeast(1))
3622  .WillRepeatedly(::testing::Return(false));
3623  FLT_FORWARD(mock_capabilities, old_capabilities, GetDefaultColorFormat);
3624  FLT_FORWARD(mock_capabilities, old_capabilities, GetDefaultStencilFormat);
3625  FLT_FORWARD(mock_capabilities, old_capabilities, SupportsOffscreenMSAA);
3626  FLT_FORWARD(mock_capabilities, old_capabilities,
3627  SupportsImplicitResolvingMSAA);
3628  FLT_FORWARD(mock_capabilities, old_capabilities, SupportsReadFromResolve);
3629  FLT_FORWARD(mock_capabilities, old_capabilities, SupportsFramebufferFetch);
3630  FLT_FORWARD(mock_capabilities, old_capabilities, SupportsSSBO);
3631  FLT_FORWARD(mock_capabilities, old_capabilities, SupportsCompute);
3632  FLT_FORWARD(mock_capabilities, old_capabilities,
3633  SupportsTextureToTextureBlits);
3634  ASSERT_TRUE(SetCapabilities(mock_capabilities).ok());
3635 
3636  auto texture = std::make_shared<Image>(CreateTextureForFixture("boston.jpg"));
3637  Canvas canvas;
3638  canvas.Scale(GetContentScale() * 0.5);
3639  canvas.DrawPaint({.color = Color::Black()});
3640  canvas.DrawImage(
3641  texture, Point(200, 200),
3642  {
3643  .image_filter = ImageFilter::MakeBlur(
3644  Sigma(20.0), Sigma(20.0), FilterContents::BlurStyle::kNormal,
3645  Entity::TileMode::kDecal),
3646  });
3647  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3648 }

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

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

Definition at line 651 of file aiks_gradient_unittests.cc.

651  {
652  // Compare with https://fiddle.skia.org/c/027392122bec8ac2b5d5de00a4b9bbe2
653  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
654  static float scale = 3;
655  static bool add_circle_clip = true;
656  const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
657  const Entity::TileMode tile_modes[] = {
658  Entity::TileMode::kClamp, Entity::TileMode::kRepeat,
659  Entity::TileMode::kMirror, Entity::TileMode::kDecal};
660  static int selected_tile_mode = 0;
661  static float alpha = 1;
662 
663  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
664  ImGui::SliderFloat("Scale", &scale, 0, 6);
665  ImGui::Checkbox("Circle clip", &add_circle_clip);
666  ImGui::SliderFloat("Alpha", &alpha, 0, 1);
667  ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
668  sizeof(tile_mode_names) / sizeof(char*));
669  ImGui::End();
670 
671  Canvas canvas;
672  canvas.Scale(GetContentScale());
673  Paint paint;
674  paint.color = Color::White();
675  canvas.DrawPaint(paint);
676 
677  paint.style = Paint::Style::kStroke;
678  paint.color = Color(1.0, 1.0, 1.0, alpha);
679  paint.stroke_width = 10;
680  auto tile_mode = tile_modes[selected_tile_mode];
681 
682  std::vector<Color> colors = {Color{0.9568, 0.2627, 0.2118, 1.0},
683  Color{0.1294, 0.5882, 0.9529, 1.0}};
684  std::vector<Scalar> stops = {0.0, 1.0};
685 
686  paint.color_source = ColorSource::MakeLinearGradient(
687  {0, 0}, {50, 50}, std::move(colors), std::move(stops), tile_mode, {});
688 
689  Path path = PathBuilder{}
690  .MoveTo({20, 20})
691  .QuadraticCurveTo({60, 20}, {60, 60})
692  .Close()
693  .MoveTo({60, 20})
694  .QuadraticCurveTo({60, 60}, {20, 60})
695  .TakePath();
696 
697  canvas.Scale(Vector2(scale, scale));
698 
699  if (add_circle_clip) {
700  auto [handle_a, handle_b] = IMPELLER_PLAYGROUND_LINE(
701  Point(60, 300), Point(600, 300), 20, Color::Red(), Color::Red());
702 
703  auto screen_to_canvas = canvas.GetCurrentTransform().Invert();
704  Point point_a = screen_to_canvas * handle_a * GetContentScale();
705  Point point_b = screen_to_canvas * handle_b * GetContentScale();
706 
707  Point middle = (point_a + point_b) / 2;
708  auto radius = point_a.GetDistance(middle);
709  canvas.ClipPath(PathBuilder{}.AddCircle(middle, radius).TakePath());
710  }
711 
712  for (auto join : {Join::kBevel, Join::kRound, Join::kMiter}) {
713  paint.stroke_join = join;
714  for (auto cap : {Cap::kButt, Cap::kSquare, Cap::kRound}) {
715  paint.stroke_cap = cap;
716  canvas.DrawPath(path.Clone(), paint);
717  canvas.Translate({80, 0});
718  }
719  canvas.Translate({-240, 60});
720  }
721 
722  return canvas.EndRecordingAsPicture();
723  };
724 
725  ASSERT_TRUE(OpenPlaygroundHere(callback));
726 }

References impeller::PathBuilder::AddCircle(), impeller::Canvas::ClipPath(), impeller::Close(), impeller::Paint::color, impeller::Paint::color_source, impeller::Canvas::DrawPaint(), impeller::Canvas::DrawPath(), impeller::Canvas::EndRecordingAsPicture(), impeller::Canvas::GetCurrentTransform(), impeller::TPoint< T >::GetDistance(), IMPELLER_PLAYGROUND_LINE, 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(), 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() [152/384]

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

Definition at line 2350 of file aiks_unittests.cc.

2350  {
2351  Canvas canvas;
2352  canvas.Scale(GetContentScale());
2353 
2354  auto test = [&canvas](const std::shared_ptr<ImageFilter>& filter) {
2355  auto DrawLine = [&canvas](const Point& p0, const Point& p1,
2356  const Paint& p) {
2357  auto path = PathBuilder{}
2358  .AddLine(p0, p1)
2359  .SetConvexity(Convexity::kConvex)
2360  .TakePath();
2361  Paint paint = p;
2362  paint.style = Paint::Style::kStroke;
2363  canvas.DrawPath(std::move(path), paint);
2364  };
2365  // Registration marks for the edge of the SaveLayer
2366  DrawLine(Point(75, 100), Point(225, 100), {.color = Color::White()});
2367  DrawLine(Point(75, 200), Point(225, 200), {.color = Color::White()});
2368  DrawLine(Point(100, 75), Point(100, 225), {.color = Color::White()});
2369  DrawLine(Point(200, 75), Point(200, 225), {.color = Color::White()});
2370 
2371  canvas.SaveLayer({.image_filter = filter},
2372  Rect::MakeLTRB(100, 100, 200, 200));
2373  {
2374  // DrawPaint to verify correct behavior when the contents are unbounded.
2375  canvas.DrawPaint({.color = Color::Yellow()});
2376 
2377  // Contrasting rectangle to see interior blurring
2378  canvas.DrawRect(Rect::MakeLTRB(125, 125, 175, 175),
2379  {.color = Color::Blue()});
2380  }
2381  canvas.Restore();
2382  };
2383 
2384  test(ImageFilter::MakeBlur(Sigma{10.0}, Sigma{10.0},
2385  FilterContents::BlurStyle::kNormal,
2386  Entity::TileMode::kDecal));
2387 
2388  canvas.Translate({200.0, 0.0});
2389 
2390  test(ImageFilter::MakeDilate(Radius{10.0}, Radius{10.0}));
2391 
2392  canvas.Translate({200.0, 0.0});
2393 
2394  test(ImageFilter::MakeErode(Radius{10.0}, Radius{10.0}));
2395 
2396  canvas.Translate({-400.0, 200.0});
2397 
2398  auto rotate_filter =
2399  ImageFilter::MakeMatrix(Matrix::MakeTranslation({150, 150}) *
2400  Matrix::MakeRotationZ(Degrees{10.0}) *
2401  Matrix::MakeTranslation({-150, -150}),
2402  SamplerDescriptor{});
2403  test(rotate_filter);
2404 
2405  canvas.Translate({200.0, 0.0});
2406 
2407  auto rgb_swap_filter = ImageFilter::MakeFromColorFilter(
2408  *ColorFilter::MakeMatrix({.array = {
2409  0, 1, 0, 0, 0, //
2410  0, 0, 1, 0, 0, //
2411  1, 0, 0, 0, 0, //
2412  0, 0, 0, 1, 0 //
2413  }}));
2414  test(rgb_swap_filter);
2415 
2416  canvas.Translate({200.0, 0.0});
2417 
2418  test(ImageFilter::MakeCompose(*rotate_filter, *rgb_swap_filter));
2419 
2420  canvas.Translate({-400.0, 200.0});
2421 
2422  test(ImageFilter::MakeLocalMatrix(Matrix::MakeTranslation({25.0, 25.0}),
2423  *rotate_filter));
2424 
2425  canvas.Translate({200.0, 0.0});
2426 
2427  test(ImageFilter::MakeLocalMatrix(Matrix::MakeTranslation({25.0, 25.0}),
2428  *rgb_swap_filter));
2429 
2430  canvas.Translate({200.0, 0.0});
2431 
2432  test(ImageFilter::MakeLocalMatrix(
2433  Matrix::MakeTranslation({25.0, 25.0}),
2434  *ImageFilter::MakeCompose(*rotate_filter, *rgb_swap_filter)));
2435 
2436  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2437 }

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

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

Definition at line 2439 of file aiks_unittests.cc.

2439  {
2440  Canvas canvas;
2441  canvas.Scale(GetContentScale());
2442 
2443  auto blur_filter = ImageFilter::MakeBlur(Sigma{10.0}, Sigma{10.0},
2444  FilterContents::BlurStyle::kNormal,
2445  Entity::TileMode::kDecal);
2446 
2447  canvas.SaveLayer({.image_filter = blur_filter}, std::nullopt);
2448  {
2449  // DrawPaint to verify correct behavior when the contents are unbounded.
2450  canvas.DrawPaint({.color = Color::Yellow()});
2451 
2452  // Contrasting rectangle to see interior blurring
2453  canvas.DrawRect(Rect::MakeLTRB(125, 125, 175, 175),
2454  {.color = Color::Blue()});
2455  }
2456  canvas.Restore();
2457 
2458  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2459 }

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

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

Definition at line 2168 of file aiks_unittests.cc.

2168  {
2169  Canvas canvas;
2170 
2171  canvas.SaveLayer({
2172  .color_filter = ColorFilter::MakeLinearToSrgb(),
2173  });
2174 
2175  canvas.Translate({500, 300, 0});
2176  canvas.Rotate(Radians(2 * kPi / 3));
2177  canvas.DrawRect(Rect::MakeXYWH(100, 100, 200, 200), {.color = Color::Blue()});
2178 
2179  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2180 }

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

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

Definition at line 3545 of file aiks_unittests.cc.

3545  {
3546  Canvas canvas;
3547 
3548  Paint paint = {
3549  .color = Color::Blue(),
3550  .mask_blur_descriptor =
3551  Paint::MaskBlurDescriptor{
3552  .style = FilterContents::BlurStyle::kNormal,
3553  .sigma = Sigma(0),
3554  },
3555  };
3556 
3557  canvas.DrawCircle({300, 300}, 200, paint);
3558  canvas.DrawRect(Rect::MakeLTRB(100, 300, 500, 600), paint);
3559 
3560  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3561 }

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

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

Definition at line 3122 of file aiks_unittests.cc.

3122  {
3123  Canvas canvas;
3124  canvas.DrawPaint({.color = Color::Black()});
3125  canvas.SaveLayer({}, std::nullopt);
3126  {
3127  canvas.DrawCircle(Point(200, 200), 100,
3128  {.color = Color::Green().WithAlpha(0.5),
3129  .blend_mode = BlendMode::kPlus});
3130  // Should render a second circle, centered on the bottom-right-most edge of
3131  // the circle.
3132  canvas.SaveLayer(
3133  {}, std::nullopt,
3134  ImageFilter::MakeMatrix(
3135  Matrix::MakeTranslation(Vector2(1, 1) * (100 + 100 * k1OverSqrt2)) *
3136  Matrix::MakeScale(Vector2(1, 1) * 0.5) *
3137  Matrix::MakeTranslation(Vector2(-100, -100)),
3138  SamplerDescriptor{}));
3139  canvas.Restore();
3140  }
3141  canvas.Restore();
3142 
3143  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3144 }

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

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

Definition at line 3420 of file aiks_unittests.cc.

3421  {
3422  Canvas canvas;
3423  canvas.Scale(GetContentScale());
3424  canvas.Translate({100, 100});
3425  // Draw a circle in a SaveLayer at -300, but move it back on-screen with a
3426  // +300 translation applied by a SaveLayer image filter.
3427  canvas.SaveLayer({
3428  .image_filter = std::make_shared<MatrixImageFilter>(
3429  Matrix::MakeTranslation({300, 0}) * Matrix::MakeScale({2, 2, 2}),
3430  SamplerDescriptor{}),
3431  });
3432  canvas.DrawCircle({-150, 0}, 50, {.color = Color::Green()});
3433  canvas.Restore();
3434 
3435  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3436 }

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

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

Definition at line 3403 of file aiks_unittests.cc.

3403  {
3404  Canvas canvas;
3405  canvas.Scale(GetContentScale());
3406  canvas.Translate({100, 100});
3407  // Draw a circle in a SaveLayer at -300, but move it back on-screen with a
3408  // +300 translation applied by a SaveLayer image filter.
3409  canvas.SaveLayer({
3410  .image_filter = std::make_shared<MatrixImageFilter>(
3411  Matrix::MakeTranslation({300, 0}), SamplerDescriptor{}),
3412  });
3413  canvas.DrawCircle({-300, 0}, 100, {.color = Color::Green()});
3414  canvas.Restore();
3415 
3416  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3417 }

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

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

Definition at line 3386 of file aiks_unittests.cc.

3386  {
3387  Canvas canvas;
3388  canvas.Scale(GetContentScale());
3389  auto image = std::make_shared<Image>(CreateTextureForFixture("airplane.jpg"));
3390  canvas.Translate({600, -200});
3391  canvas.SaveLayer({
3392  .image_filter = std::make_shared<MatrixImageFilter>(
3393  Matrix::MakeScale({2, 2, 2}), SamplerDescriptor{}),
3394  });
3395  canvas.DrawImage(image, {0, 0},
3396  Paint{.color = Color::White().WithAlpha(0.5)});
3397  canvas.Restore();
3398 
3399  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3400 }

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

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

Definition at line 3095 of file aiks_unittests.cc.

3095  {
3096  Canvas canvas;
3097  canvas.DrawPaint({.color = Color::Black()});
3098  canvas.SaveLayer({}, std::nullopt);
3099  {
3100  canvas.DrawCircle(Point(200, 200), 100,
3101  {.color = Color::Green().WithAlpha(0.5),
3102  .blend_mode = BlendMode::kPlus});
3103  // Should render a second circle, centered on the bottom-right-most edge of
3104  // the circle.
3105  canvas.SaveLayer({.image_filter = ImageFilter::MakeMatrix(
3106  Matrix::MakeTranslation(Vector2(1, 1) *
3107  (200 + 100 * k1OverSqrt2)) *
3108  Matrix::MakeScale(Vector2(1, 1) * 0.5) *
3109  Matrix::MakeTranslation(Vector2(-200, -200)),
3110  SamplerDescriptor{})},
3111  std::nullopt);
3112  canvas.DrawCircle(Point(200, 200), 100,
3113  {.color = Color::Green().WithAlpha(0.5),
3114  .blend_mode = BlendMode::kPlus});
3115  canvas.Restore();
3116  }
3117  canvas.Restore();
3118 
3119  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3120 }

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

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

Definition at line 1889 of file aiks_unittests.cc.

1889  {
1890  auto entity_pass = std::make_shared<EntityPass>();
1891  auto rect = Rect::MakeLTRB(0, 0, 100, 100);
1892  Paint paint;
1893  paint.color = Color::White().WithAlpha(0.5);
1894  paint.color_filter =
1895  ColorFilter::MakeBlend(BlendMode::kSourceOver, Color::Blue());
1896 
1897  // Paint has color filter, can't elide.
1898  auto delegate = std::make_shared<OpacityPeepholePassDelegate>(paint);
1899  ASSERT_FALSE(delegate->CanCollapseIntoParentPass(entity_pass.get()));
1900 
1901  paint.color_filter = nullptr;
1902  paint.image_filter = ImageFilter::MakeBlur(Sigma(1.0), Sigma(1.0),
1903  FilterContents::BlurStyle::kNormal,
1904  Entity::TileMode::kClamp);
1905 
1906  // Paint has image filter, can't elide.
1907  delegate = std::make_shared<OpacityPeepholePassDelegate>(paint);
1908  ASSERT_FALSE(delegate->CanCollapseIntoParentPass(entity_pass.get()));
1909 
1910  paint.image_filter = nullptr;
1911  paint.color = Color::Red();
1912 
1913  // Paint has no alpha, can't elide;
1914  delegate = std::make_shared<OpacityPeepholePassDelegate>(paint);
1915  ASSERT_FALSE(delegate->CanCollapseIntoParentPass(entity_pass.get()));
1916 
1917  // Positive test.
1918  Entity entity;
1919  entity.SetContents(SolidColorContents::Make(
1920  PathBuilder{}.AddRect(rect).TakePath(), Color::Red()));
1921  entity_pass->AddEntity(std::move(entity));
1922  paint.color = Color::Red().WithAlpha(0.5);
1923 
1924  delegate = std::make_shared<OpacityPeepholePassDelegate>(paint);
1925  ASSERT_TRUE(delegate->CanCollapseIntoParentPass(entity_pass.get()));
1926 }

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

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

Definition at line 2601 of file aiks_unittests.cc.

2601  {
2602  Canvas canvas;
2603  canvas.Scale(Vector2(1.618, 1.618));
2604  canvas.DrawCircle(Point(), 10,
2605  {
2606  .color = Color::CornflowerBlue(),
2607  .blend_mode = BlendMode::kSourceOver,
2608  });
2609  Picture picture = canvas.EndRecordingAsPicture();
2610 
2611  // Extract the SolidColorSource.
2612  // Entity entity;
2613  std::vector<Entity> entity;
2614  std::shared_ptr<SolidColorContents> contents;
2615  picture.pass->IterateAllEntities([e = &entity, &contents](Entity& entity) {
2616  if (ScalarNearlyEqual(entity.GetTransform().GetScale().x, 1.618f)) {
2617  contents =
2618  std::static_pointer_cast<SolidColorContents>(entity.GetContents());
2619  e->emplace_back(entity.Clone());
2620  return false;
2621  }
2622  return true;
2623  });
2624 
2625  ASSERT_TRUE(entity.size() >= 1);
2626  ASSERT_TRUE(contents->IsOpaque());
2627  ASSERT_EQ(entity[0].GetBlendMode(), BlendMode::kSource);
2628 }

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

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

Definition at line 1053 of file aiks_unittests.cc.

1053  {
1054  Paint paint;
1055  Canvas canvas;
1056  // Default is kSourceOver.
1057  paint.color = Color(1, 0, 0, 0.5);
1058  canvas.DrawCircle(Point(150, 200), 100, paint);
1059  paint.color = Color(0, 1, 0, 0.5);
1060  canvas.DrawCircle(Point(250, 200), 100, paint);
1061 
1062  paint.blend_mode = BlendMode::kPlus;
1063  paint.color = Color::Red();
1064  canvas.DrawCircle(Point(450, 250), 100, paint);
1065  paint.color = Color::Green();
1066  canvas.DrawCircle(Point(550, 250), 100, paint);
1067  paint.color = Color::Blue();
1068  canvas.DrawCircle(Point(500, 150), 100, paint);
1069  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1070 }

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

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

Definition at line 1862 of file aiks_unittests.cc.

1862  {
1863  // validate that a paint with a color filter "HasFilters", no other filters
1864  // impact this setting.
1865  Paint paint;
1866 
1867  ASSERT_FALSE(paint.HasColorFilter());
1868 
1869  paint.color_filter =
1870  ColorFilter::MakeBlend(BlendMode::kSourceOver, Color::Blue());
1871 
1872  ASSERT_TRUE(paint.HasColorFilter());
1873 
1874  paint.image_filter = ImageFilter::MakeBlur(Sigma(1.0), Sigma(1.0),
1875  FilterContents::BlurStyle::kNormal,
1876  Entity::TileMode::kClamp);
1877 
1878  ASSERT_TRUE(paint.HasColorFilter());
1879 
1880  paint.mask_blur_descriptor = {};
1881 
1882  ASSERT_TRUE(paint.HasColorFilter());
1883 
1884  paint.color_filter = nullptr;
1885 
1886  ASSERT_FALSE(paint.HasColorFilter());
1887 }

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

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

Definition at line 1952 of file aiks_unittests.cc.

1953  {
1954  Canvas canvas;
1955  canvas.SaveLayer({}, std::nullopt, ImageFilter::MakeMatrix(Matrix(), {}));
1956  canvas.DrawPaint({.color = Color::Red(), .blend_mode = BlendMode::kSource});
1957  canvas.DrawPaint({.color = Color::CornflowerBlue().WithAlpha(0.75),
1958  .blend_mode = BlendMode::kSourceOver});
1959  canvas.Restore();
1960 
1961  Picture picture = canvas.EndRecordingAsPicture();
1962 
1963  std::shared_ptr<ContextSpy> spy = ContextSpy::Make();
1964  std::shared_ptr<Context> real_context = GetContext();
1965  std::shared_ptr<ContextMock> mock_context = spy->MakeContext(real_context);
1966  AiksContext renderer(mock_context, nullptr);
1967  std::shared_ptr<Image> image = picture.ToImage(renderer, {300, 300});
1968 
1969  ASSERT_EQ(spy->render_passes_.size(), 3llu);
1970  std::shared_ptr<RenderPass> render_pass = spy->render_passes_[0];
1971  ASSERT_EQ(render_pass->GetCommands().size(), 0llu);
1972 }

References impeller::Color::CornflowerBlue(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), 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() [166/384]

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

Definition at line 3191 of file aiks_unittests.cc.

3191  {
3192  Canvas canvas;
3193 
3194  // Should render a green square in the middle of a blue circle.
3195  canvas.SaveLayer({});
3196  {
3197  canvas.Translate(Point(100, 100));
3198  canvas.DrawCircle(Point(200, 200), 200, {.color = Color::Blue()});
3199  canvas.ClipRect(Rect::MakeXYWH(100, 100, 200, 200));
3200  canvas.DrawCircle(Point(200, 200), 200,
3201  {
3202  .color = Color::Green(),
3203  .blend_mode = BlendMode::kSourceOver,
3204  .image_filter = ImageFilter::MakeFromColorFilter(
3205  *ColorFilter::MakeBlend(BlendMode::kDestination,
3206  Color::White())),
3207  });
3208  canvas.Restore();
3209  }
3210 
3211  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3212 }

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

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

Definition at line 3279 of file aiks_unittests.cc.

3279  {
3280  auto context = GetContext();
3281  std::weak_ptr<Texture> weak_texture;
3282 
3283  {
3284  auto texture = CreateTextureForFixture("table_mountain_nx.png");
3285 
3286  Canvas canvas;
3287  canvas.Scale(GetContentScale());
3288  canvas.Translate({100.0f, 100.0f, 0});
3289 
3290  Paint paint;
3291  paint.color_source = ColorSource::MakeImage(
3292  texture, Entity::TileMode::kClamp, Entity::TileMode::kClamp, {}, {});
3293  canvas.DrawRect(Rect::MakeXYWH(0, 0, 600, 600), paint);
3294 
3295  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3296  }
3297 
3298  // See https://github.com/flutter/flutter/issues/134751.
3299  //
3300  // If the fence waiter was working this may not be released by the end of the
3301  // scope above. Adding a manual shutdown so that future changes to the fence
3302  // waiter will not flake this test.
3303  context->Shutdown();
3304 
3305  // The texture should be released by now.
3306  ASSERT_TRUE(weak_texture.expired()) << "When the texture is no longer in use "
3307  "by the backend, it should be "
3308  "released.";
3309 }

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

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(std::move(arrow_stem), paint);
41  canvas.DrawPath(std::move(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() [169/384]

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

Definition at line 1712 of file aiks_unittests.cc.

1712  {
1713  // Compare with https://fiddle.skia.org/c/9e03de8567ffb49e7e83f53b64bcf636
1714  Canvas canvas;
1715  Paint paint;
1716 
1717  paint.color = Color::Black();
1718  Rect rect = Rect::MakeXYWH(25, 25, 25, 25);
1719  canvas.DrawRect(rect, paint);
1720 
1721  canvas.Translate({10, 10});
1722  canvas.SaveLayer({});
1723 
1724  paint.color = Color::Green();
1725  canvas.DrawRect(rect, paint);
1726 
1727  canvas.Restore();
1728 
1729  canvas.Translate({10, 10});
1730  paint.color = Color::Red();
1731  canvas.DrawRect(rect, paint);
1732 
1733  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1734 }

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

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

Definition at line 1793 of file aiks_unittests.cc.

1793  {
1794  Canvas canvas;
1795  canvas.Scale(GetContentScale());
1796  canvas.Translate(Vector2(100, 100));
1797 
1798  auto texture = std::make_shared<Image>(CreateTextureForFixture("boston.jpg"));
1799  auto draw_image_layer = [&canvas, &texture](const Paint& paint) {
1800  canvas.SaveLayer(paint);
1801  canvas.DrawImage(texture, {}, Paint{});
1802  canvas.Restore();
1803  };
1804 
1805  Paint effect_paint;
1806  effect_paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
1807  .style = FilterContents::BlurStyle::kNormal,
1808  .sigma = Sigma{6},
1809  };
1810  draw_image_layer(effect_paint);
1811 
1812  canvas.Translate(Vector2(300, 300));
1813  canvas.Scale(Vector2(3, 3));
1814  draw_image_layer(effect_paint);
1815 
1816  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1817 }

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

impeller::testing::TEST_P ( AiksTest  ,
SiblingSaveLayerBoundsAreRespected   
)

Definition at line 1736 of file aiks_unittests.cc.

1736  {
1737  Canvas canvas;
1738  Paint paint;
1739  Rect rect = Rect::MakeXYWH(0, 0, 1000, 1000);
1740 
1741  // Black, green, and red squares offset by [10, 10].
1742  {
1743  canvas.SaveLayer({}, Rect::MakeXYWH(25, 25, 25, 25));
1744  paint.color = Color::Black();
1745  canvas.DrawRect(rect, paint);
1746  canvas.Restore();
1747  }
1748 
1749  {
1750  canvas.SaveLayer({}, Rect::MakeXYWH(35, 35, 25, 25));
1751  paint.color = Color::Green();
1752  canvas.DrawRect(rect, paint);
1753  canvas.Restore();
1754  }
1755 
1756  {
1757  canvas.SaveLayer({}, Rect::MakeXYWH(45, 45, 25, 25));
1758  paint.color = Color::Red();
1759  canvas.DrawRect(rect, paint);
1760  canvas.Restore();
1761  }
1762 
1763  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1764 }

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() [172/384]

impeller::testing::TEST_P ( AiksTest  ,
SolidColorApplyColorFilter   
)

Definition at line 3146 of file aiks_unittests.cc.

3146  {
3147  auto contents = SolidColorContents();
3148  contents.SetColor(Color::CornflowerBlue().WithAlpha(0.75));
3149  auto result = contents.ApplyColorFilter([](const Color& color) {
3150  return color.Blend(Color::LimeGreen().WithAlpha(0.75), BlendMode::kScreen);
3151  });
3152  ASSERT_TRUE(result);
3153  ASSERT_COLOR_NEAR(contents.GetColor(),
3154  Color(0.433247, 0.879523, 0.825324, 0.75));
3155 }

References ASSERT_COLOR_NEAR, impeller::Color::Blend(), impeller::Color::CornflowerBlue(), impeller::kScreen, and impeller::Color::LimeGreen().

◆ TEST_P() [173/384]

impeller::testing::TEST_P ( AiksTest  ,
SolidColorCirclesOvalsRRectsMaskBlurCorrectly   
)

Definition at line 1524 of file aiks_unittests.cc.

1524  {
1525  Canvas canvas;
1526  canvas.Scale(GetContentScale());
1527  Paint paint;
1528  paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
1529  .style = FilterContents::BlurStyle::kNormal,
1530  .sigma = Sigma{1},
1531  };
1532 
1533  canvas.DrawPaint({.color = Color::White()});
1534 
1535  paint.color = Color::Crimson();
1536  Scalar y = 100.0f;
1537  for (int i = 0; i < 5; i++) {
1538  Scalar x = (i + 1) * 100;
1539  Scalar radius = x / 10.0f;
1540  canvas.DrawRect(Rect::MakeXYWH(x + 25 - radius / 2, y + radius / 2, //
1541  radius, 60.0f - radius),
1542  paint);
1543  }
1544 
1545  paint.color = Color::Blue();
1546  y += 100.0f;
1547  for (int i = 0; i < 5; i++) {
1548  Scalar x = (i + 1) * 100;
1549  Scalar radius = x / 10.0f;
1550  canvas.DrawCircle({x + 25, y + 25}, radius, paint);
1551  }
1552 
1553  paint.color = Color::Green();
1554  y += 100.0f;
1555  for (int i = 0; i < 5; i++) {
1556  Scalar x = (i + 1) * 100;
1557  Scalar radius = x / 10.0f;
1558  canvas.DrawOval(Rect::MakeXYWH(x + 25 - radius / 2, y + radius / 2, //
1559  radius, 60.0f - radius),
1560  paint);
1561  }
1562 
1563  paint.color = Color::Purple();
1564  y += 100.0f;
1565  for (int i = 0; i < 5; i++) {
1566  Scalar x = (i + 1) * 100;
1567  Scalar radius = x / 20.0f;
1568  canvas.DrawRRect(Rect::MakeXYWH(x, y, 60.0f, 60.0f), //
1569  {radius, radius}, //
1570  paint);
1571  }
1572 
1573  paint.color = Color::Orange();
1574  y += 100.0f;
1575  for (int i = 0; i < 5; i++) {
1576  Scalar x = (i + 1) * 100;
1577  Scalar radius = x / 20.0f;
1578  canvas.DrawRRect(Rect::MakeXYWH(x, y, 60.0f, 60.0f), //
1579  {radius, 5.0f}, paint);
1580  }
1581 
1582  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1583 }

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() [174/384]

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  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
189  ImGui::ColorEdit4("Color", reinterpret_cast<float*>(&color));
190  ImGui::SliderFloat("Scale", &scale, 0, 6);
191  ImGui::Checkbox("Circle clip", &add_circle_clip);
192  ImGui::End();
193 
194  Canvas canvas;
195  canvas.Scale(GetContentScale());
196  Paint paint;
197 
198  paint.color = Color::White();
199  canvas.DrawPaint(paint);
200 
201  paint.color = color;
202  paint.style = Paint::Style::kStroke;
203  paint.stroke_width = 10;
204 
205  Path path = PathBuilder{}
206  .MoveTo({20, 20})
207  .QuadraticCurveTo({60, 20}, {60, 60})
208  .Close()
209  .MoveTo({60, 20})
210  .QuadraticCurveTo({60, 60}, {20, 60})
211  .TakePath();
212 
213  canvas.Scale(Vector2(scale, scale));
214 
215  if (add_circle_clip) {
216  auto [handle_a, handle_b] = IMPELLER_PLAYGROUND_LINE(
217  Point(60, 300), Point(600, 300), 20, Color::Red(), Color::Red());
218 
219  auto screen_to_canvas = canvas.GetCurrentTransform().Invert();
220  Point point_a = screen_to_canvas * handle_a * GetContentScale();
221  Point point_b = screen_to_canvas * handle_b * GetContentScale();
222 
223  Point middle = (point_a + point_b) / 2;
224  auto radius = point_a.GetDistance(middle);
225  canvas.ClipPath(PathBuilder{}.AddCircle(middle, radius).TakePath());
226  }
227 
228  for (auto join : {Join::kBevel, Join::kRound, Join::kMiter}) {
229  paint.stroke_join = join;
230  for (auto cap : {Cap::kButt, Cap::kSquare, Cap::kRound}) {
231  paint.stroke_cap = cap;
232  canvas.DrawPath(path.Clone(), paint);
233  canvas.Translate({80, 0});
234  }
235  canvas.Translate({-240, 60});
236  }
237 
238  return canvas.EndRecordingAsPicture();
239  };
240 
241  ASSERT_TRUE(OpenPlaygroundHere(callback));
242 }

References impeller::PathBuilder::AddCircle(), impeller::Color::Black(), impeller::Canvas::ClipPath(), impeller::Path::Clone(), impeller::Close(), impeller::Paint::color, impeller::Canvas::DrawPaint(), impeller::Canvas::DrawPath(), impeller::Canvas::EndRecordingAsPicture(), impeller::Canvas::GetCurrentTransform(), impeller::TPoint< T >::GetDistance(), IMPELLER_PLAYGROUND_LINE, 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(), 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() [175/384]

impeller::testing::TEST_P ( AiksTest  ,
SrgbToLinearFilterSubpassCollapseOptimization   
)

Definition at line 2182 of file aiks_unittests.cc.

2182  {
2183  Canvas canvas;
2184 
2185  canvas.SaveLayer({
2186  .color_filter = ColorFilter::MakeSrgbToLinear(),
2187  });
2188 
2189  canvas.Translate({500, 300, 0});
2190  canvas.Rotate(Radians(2 * kPi / 3));
2191  canvas.DrawRect(Rect::MakeXYWH(100, 100, 200, 200), {.color = Color::Blue()});
2192 
2193  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2194 }

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() [176/384]

impeller::testing::TEST_P ( AiksTest  ,
StrokedCirclesRenderCorrectly   
)

Definition at line 1306 of file aiks_unittests.cc.

1306  {
1307  Canvas canvas;
1308  canvas.Scale(GetContentScale());
1309  Paint paint;
1310  const int color_count = 3;
1311  Color colors[color_count] = {
1312  Color::Blue(),
1313  Color::Green(),
1314  Color::Crimson(),
1315  };
1316 
1317  paint.color = Color::White();
1318  canvas.DrawPaint(paint);
1319 
1320  int c_index = 0;
1321 
1322  auto draw = [&paint, &colors, &c_index](Canvas& canvas, Point center,
1323  Scalar r, Scalar dr, int n) {
1324  for (int i = 0; i < n; i++) {
1325  paint.color = colors[(c_index++) % color_count];
1326  canvas.DrawCircle(center, r, paint);
1327  r += dr;
1328  }
1329  };
1330 
1331  paint.style = Paint::Style::kStroke;
1332  paint.stroke_width = 1;
1333  draw(canvas, {10, 10}, 2, 2, 14); // r = [2, 28], covers [1,29]
1334  paint.stroke_width = 5;
1335  draw(canvas, {10, 10}, 35, 10, 56); // r = [35, 585], covers [30,590]
1336 
1337  std::vector<Color> gradient_colors = {
1338  Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0},
1339  Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0},
1340  Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0},
1341  Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0},
1342  Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0},
1343  Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0},
1344  Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}};
1345  std::vector<Scalar> stops = {
1346  0.0,
1347  (1.0 / 6.0) * 1,
1348  (1.0 / 6.0) * 2,
1349  (1.0 / 6.0) * 3,
1350  (1.0 / 6.0) * 4,
1351  (1.0 / 6.0) * 5,
1352  1.0,
1353  };
1354  auto texture = CreateTextureForFixture("airplane.jpg",
1355  /*enable_mipmapping=*/true);
1356 
1357  paint.color_source = ColorSource::MakeRadialGradient(
1358  {500, 600}, 75, std::move(gradient_colors), std::move(stops),
1359  Entity::TileMode::kMirror, {});
1360  draw(canvas, {500, 600}, 5, 10, 10);
1361 
1362  paint.color_source = ColorSource::MakeImage(
1363  texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {},
1364  Matrix::MakeTranslation({700, 200}));
1365  draw(canvas, {800, 300}, 5, 10, 10);
1366 
1367  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1368 }

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() [177/384]

impeller::testing::TEST_P ( AiksTest  ,
SubpassWithClearColorOptimization   
)

Definition at line 3766 of file aiks_unittests.cc.

3766  {
3767  Canvas canvas;
3768 
3769  // Use a non-srcOver blend mode to ensure that we don't detect this as an
3770  // opacity peephole optimization.
3771  canvas.SaveLayer(
3772  {.color = Color::Blue().WithAlpha(0.5), .blend_mode = BlendMode::kSource},
3773  Rect::MakeLTRB(0, 0, 200, 200));
3774  canvas.DrawPaint(
3775  {.color = Color::BlackTransparent(), .blend_mode = BlendMode::kSource});
3776  canvas.Restore();
3777 
3778  canvas.SaveLayer(
3779  {.color = Color::Blue(), .blend_mode = BlendMode::kDestinationOver});
3780  canvas.Restore();
3781 
3782  // This playground should appear blank on CI since we are only drawing
3783  // transparent black. If the clear color optimization is broken, the texture
3784  // will be filled with NaNs and may produce a magenta texture on macOS or iOS.
3785  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3786 }

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() [178/384]

impeller::testing::TEST_P ( AiksTest  ,
TextForegroundShaderWithTransform   
)

Definition at line 2963 of file aiks_unittests.cc.

2963  {
2964  auto mapping = flutter::testing::OpenFixtureAsSkData("Roboto-Regular.ttf");
2965  ASSERT_NE(mapping, nullptr);
2966 
2967  Scalar font_size = 100;
2968  sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
2969  SkFont sk_font(font_mgr->makeFromData(mapping), font_size);
2970 
2971  Paint text_paint;
2972  text_paint.color = Color::Blue();
2973 
2974  std::vector<Color> colors = {Color{0.9568, 0.2627, 0.2118, 1.0},
2975  Color{0.1294, 0.5882, 0.9529, 1.0}};
2976  std::vector<Scalar> stops = {
2977  0.0,
2978  1.0,
2979  };
2980  text_paint.color_source = ColorSource::MakeLinearGradient(
2981  {0, 0}, {100, 100}, std::move(colors), std::move(stops),
2982  Entity::TileMode::kRepeat, {});
2983 
2984  Canvas canvas;
2985  canvas.Translate({100, 100});
2986  canvas.Rotate(Radians(kPi / 4));
2987 
2988  auto blob = SkTextBlob::MakeFromString("Hello", sk_font);
2989  ASSERT_NE(blob, nullptr);
2990  auto frame = MakeTextFrameFromTextBlobSkia(blob);
2991  canvas.DrawTextFrame(frame, Point(), text_paint);
2992 
2993  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2994 }

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() [179/384]

impeller::testing::TEST_P ( AiksTest  ,
TextFrameSubpixelAlignment   
)

Definition at line 771 of file aiks_unittests.cc.

771  {
772  std::array<Scalar, 20> phase_offsets;
773  for (Scalar& offset : phase_offsets) {
774  auto rand = std::rand(); // NOLINT
775  offset = (static_cast<float>(rand) / static_cast<float>(RAND_MAX)) * k2Pi;
776  }
777 
778  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
779  static float font_size = 20;
780  static float phase_variation = 0.2;
781  static float speed = 0.5;
782  static float magnitude = 100;
783  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
784  ImGui::SliderFloat("Font size", &font_size, 5, 50);
785  ImGui::SliderFloat("Phase variation", &phase_variation, 0, 1);
786  ImGui::SliderFloat("Oscillation speed", &speed, 0, 2);
787  ImGui::SliderFloat("Oscillation magnitude", &magnitude, 0, 300);
788  ImGui::End();
789 
790  Canvas canvas;
791  canvas.Scale(GetContentScale());
792 
793  for (size_t i = 0; i < phase_offsets.size(); i++) {
794  auto position = Point(
795  200 + magnitude * std::sin((-phase_offsets[i] * phase_variation +
796  GetSecondsElapsed() * speed)), //
797  200 + i * font_size * 1.1 //
798  );
800  GetContext(), canvas,
801  "the quick brown fox jumped over "
802  "the lazy dog!.?",
803  "Roboto-Regular.ttf",
804  {.font_size = font_size, .position = position})) {
805  return std::nullopt;
806  }
807  }
808  return canvas.EndRecordingAsPicture();
809  };
810 
811  ASSERT_TRUE(OpenPlaygroundHere(callback));
812 }

References impeller::Canvas::EndRecordingAsPicture(), impeller::k2Pi, RenderTextInCanvasSkia(), and impeller::Canvas::Scale().

◆ TEST_P() [180/384]

impeller::testing::TEST_P ( AiksTest  ,
TextRotated   
)

Definition at line 923 of file aiks_unittests.cc.

923  {
924  Canvas canvas;
925  canvas.Scale(GetContentScale());
926  canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
927 
928  canvas.Transform(Matrix(0.25, -0.3, 0, -0.002, //
929  0, 0.5, 0, 0, //
930  0, 0, 0.3, 0, //
931  100, 100, 0, 1.3));
932  ASSERT_TRUE(RenderTextInCanvasSkia(
933  GetContext(), canvas, "the quick brown fox jumped over the lazy dog!.?",
934  "Roboto-Regular.ttf"));
935 
936  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
937 }

References impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), RenderTextInCanvasSkia(), impeller::Canvas::Scale(), and impeller::Canvas::Transform().

◆ TEST_P() [181/384]

impeller::testing::TEST_P ( AiksTest  ,
TransformMultipliesCorrectly   
)

Definition at line 1208 of file aiks_unittests.cc.

1208  {
1209  Canvas canvas;
1210  ASSERT_MATRIX_NEAR(canvas.GetCurrentTransform(), Matrix());
1211 
1212  // clang-format off
1213  canvas.Translate(Vector3(100, 200));
1215  canvas.GetCurrentTransform(),
1216  Matrix( 1, 0, 0, 0,
1217  0, 1, 0, 0,
1218  0, 0, 1, 0,
1219  100, 200, 0, 1));
1220 
1221  canvas.Rotate(Radians(kPiOver2));
1223  canvas.GetCurrentTransform(),
1224  Matrix( 0, 1, 0, 0,
1225  -1, 0, 0, 0,
1226  0, 0, 1, 0,
1227  100, 200, 0, 1));
1228 
1229  canvas.Scale(Vector3(2, 3));
1231  canvas.GetCurrentTransform(),
1232  Matrix( 0, 2, 0, 0,
1233  -3, 0, 0, 0,
1234  0, 0, 0, 0,
1235  100, 200, 0, 1));
1236 
1237  canvas.Translate(Vector3(100, 200));
1239  canvas.GetCurrentTransform(),
1240  Matrix( 0, 2, 0, 0,
1241  -3, 0, 0, 0,
1242  0, 0, 0, 0,
1243  -500, 400, 0, 1));
1244  // clang-format on
1245 }

References ASSERT_MATRIX_NEAR, impeller::Canvas::GetCurrentTransform(), impeller::kPiOver2, impeller::Canvas::Rotate(), impeller::Canvas::Scale(), and impeller::Canvas::Translate().

◆ TEST_P() [182/384]

impeller::testing::TEST_P ( AiksTest  ,
TranslucentSaveLayerDrawsCorrectly   
)

Definition at line 2288 of file aiks_unittests.cc.

2288  {
2289  Canvas canvas;
2290 
2291  canvas.DrawRect(Rect::MakeXYWH(100, 100, 300, 300), {.color = Color::Blue()});
2292 
2293  canvas.SaveLayer({.color = Color::Black().WithAlpha(0.5)});
2294  canvas.DrawRect(Rect::MakeXYWH(100, 500, 300, 300), {.color = Color::Blue()});
2295  canvas.Restore();
2296 
2297  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2298 }

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() [183/384]

impeller::testing::TEST_P ( AiksTest  ,
TranslucentSaveLayerImageDrawsCorrectly   
)

Definition at line 2461 of file aiks_unittests.cc.

2461  {
2462  Canvas canvas;
2463 
2464  auto image = std::make_shared<Image>(CreateTextureForFixture("airplane.jpg"));
2465  canvas.DrawImage(image, {100, 100}, {});
2466 
2467  canvas.SaveLayer({.color = Color::Black().WithAlpha(0.5)});
2468  canvas.DrawImage(image, {100, 500}, {});
2469  canvas.Restore();
2470 
2471  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2472 }

References impeller::Color::Black(), impeller::Canvas::DrawImage(), impeller::Canvas::EndRecordingAsPicture(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Color::WithAlpha().

◆ TEST_P() [184/384]

impeller::testing::TEST_P ( AiksTest  ,
TranslucentSaveLayerWithAdvancedBlendModeDrawsCorrectly   
)

Definition at line 2545 of file aiks_unittests.cc.

2545  {
2546  Canvas canvas;
2547  canvas.DrawRect(Rect::MakeXYWH(0, 0, 400, 400), {.color = Color::Red()});
2548  canvas.SaveLayer({
2549  .color = Color::Black().WithAlpha(0.5),
2550  .blend_mode = BlendMode::kLighten,
2551  });
2552  canvas.DrawCircle({200, 200}, 100, {.color = Color::Green()});
2553  canvas.Restore();
2554  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2555 }

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() [185/384]

impeller::testing::TEST_P ( AiksTest  ,
TranslucentSaveLayerWithBlendColorFilterDrawsCorrectly   
)

Definition at line 2300 of file aiks_unittests.cc.

2300  {
2301  Canvas canvas;
2302 
2303  canvas.DrawRect(Rect::MakeXYWH(100, 100, 300, 300), {.color = Color::Blue()});
2304 
2305  canvas.SaveLayer({
2306  .color = Color::Black().WithAlpha(0.5),
2307  .color_filter =
2308  ColorFilter::MakeBlend(BlendMode::kDestinationOver, Color::Red()),
2309  });
2310  canvas.DrawRect(Rect::MakeXYWH(100, 500, 300, 300), {.color = Color::Blue()});
2311  canvas.Restore();
2312 
2313  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2314 }

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() [186/384]

impeller::testing::TEST_P ( AiksTest  ,
TranslucentSaveLayerWithBlendImageFilterDrawsCorrectly   
)

Definition at line 2316 of file aiks_unittests.cc.

2316  {
2317  Canvas canvas;
2318 
2319  canvas.DrawRect(Rect::MakeXYWH(100, 100, 300, 300), {.color = Color::Blue()});
2320 
2321  canvas.SaveLayer({
2322  .color = Color::Black().WithAlpha(0.5),
2323  .image_filter = ImageFilter::MakeFromColorFilter(
2324  *ColorFilter::MakeBlend(BlendMode::kDestinationOver, Color::Red())),
2325  });
2326 
2327  canvas.DrawRect(Rect::MakeXYWH(100, 500, 300, 300), {.color = Color::Blue()});
2328  canvas.Restore();
2329 
2330  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2331 }

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() [187/384]

impeller::testing::TEST_P ( AiksTest  ,
TranslucentSaveLayerWithColorAndImageFilterDrawsCorrectly   
)

Definition at line 2333 of file aiks_unittests.cc.

2333  {
2334  Canvas canvas;
2335 
2336  canvas.DrawRect(Rect::MakeXYWH(100, 100, 300, 300), {.color = Color::Blue()});
2337 
2338  canvas.SaveLayer({
2339  .color = Color::Black().WithAlpha(0.5),
2340  .color_filter =
2341  ColorFilter::MakeBlend(BlendMode::kDestinationOver, Color::Red()),
2342  });
2343 
2344  canvas.DrawRect(Rect::MakeXYWH(100, 500, 300, 300), {.color = Color::Blue()});
2345  canvas.Restore();
2346 
2347  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2348 }

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() [188/384]

impeller::testing::TEST_P ( AiksTest  ,
TranslucentSaveLayerWithColorFilterAndImageFilterDrawsCorrectly   
)

Definition at line 2519 of file aiks_unittests.cc.

2520  {
2521  Canvas canvas;
2522 
2523  auto image = std::make_shared<Image>(CreateTextureForFixture("airplane.jpg"));
2524  canvas.DrawImage(image, {100, 100}, {});
2525 
2526  canvas.SaveLayer({
2527  .color = Color::Black().WithAlpha(0.5),
2528  .image_filter = ImageFilter::MakeFromColorFilter(
2529  *ColorFilter::MakeMatrix({.array =
2530  {
2531  1, 0, 0, 0, 0, //
2532  0, 1, 0, 0, 0, //
2533  0, 0.2, 1, 0, 0, //
2534  0, 0, 0, 0.5, 0 //
2535  }})),
2536  .color_filter =
2537  ColorFilter::MakeBlend(BlendMode::kModulate, Color::Green()),
2538  });
2539  canvas.DrawImage(image, {100, 500}, {});
2540  canvas.Restore();
2541 
2542  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2543 }

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() [189/384]

impeller::testing::TEST_P ( AiksTest  ,
TranslucentSaveLayerWithColorMatrixColorFilterDrawsCorrectly   
)

Definition at line 2474 of file aiks_unittests.cc.

2474  {
2475  Canvas canvas;
2476 
2477  auto image = std::make_shared<Image>(CreateTextureForFixture("airplane.jpg"));
2478  canvas.DrawImage(image, {100, 100}, {});
2479 
2480  canvas.SaveLayer({
2481  .color = Color::Black().WithAlpha(0.5),
2482  .color_filter = ColorFilter::MakeMatrix({.array =
2483  {
2484  1, 0, 0, 0, 0, //
2485  0, 1, 0, 0, 0, //
2486  0, 0, 1, 0, 0, //
2487  0, 0, 0, 2, 0 //
2488  }}),
2489  });
2490  canvas.DrawImage(image, {100, 500}, {});
2491  canvas.Restore();
2492 
2493  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2494 }

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() [190/384]

impeller::testing::TEST_P ( AiksTest  ,
TranslucentSaveLayerWithColorMatrixImageFilterDrawsCorrectly   
)

Definition at line 2496 of file aiks_unittests.cc.

2496  {
2497  Canvas canvas;
2498 
2499  auto image = std::make_shared<Image>(CreateTextureForFixture("airplane.jpg"));
2500  canvas.DrawImage(image, {100, 100}, {});
2501 
2502  canvas.SaveLayer({
2503  .color = Color::Black().WithAlpha(0.5),
2504  .image_filter = ImageFilter::MakeFromColorFilter(
2505  *ColorFilter::MakeMatrix({.array =
2506  {
2507  1, 0, 0, 0, 0, //
2508  0, 1, 0, 0, 0, //
2509  0, 0, 1, 0, 0, //
2510  0, 0, 0, 2, 0 //
2511  }})),
2512  });
2513  canvas.DrawImage(image, {100, 500}, {});
2514  canvas.Restore();
2515 
2516  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2517 }

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() [191/384]

impeller::testing::TEST_P ( AiksTest  ,
VerticesGeometryUVPositionData   
)

Definition at line 3312 of file aiks_unittests.cc.

3312  {
3313  Canvas canvas;
3314  Paint paint;
3315  auto texture = CreateTextureForFixture("table_mountain_nx.png");
3316 
3317  paint.color_source = ColorSource::MakeImage(texture, Entity::TileMode::kClamp,
3318  Entity::TileMode::kClamp, {}, {});
3319 
3320  auto vertices = {Point(0, 0), Point(texture->GetSize().width, 0),
3321  Point(0, texture->GetSize().height)};
3322  std::vector<uint16_t> indices = {0u, 1u, 2u};
3323  std::vector<Point> texture_coordinates = {};
3324  std::vector<Color> vertex_colors = {};
3325  auto geometry = std::make_shared<VerticesGeometry>(
3326  vertices, indices, texture_coordinates, vertex_colors,
3327  Rect::MakeLTRB(0, 0, 1, 1), VerticesGeometry::VertexMode::kTriangleStrip);
3328 
3329  canvas.DrawVertices(geometry, BlendMode::kSourceOver, paint);
3330  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3331 }

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() [192/384]

impeller::testing::TEST_P ( AiksTest  ,
VerticesGeometryUVPositionDataWithTranslate   
)

Definition at line 3334 of file aiks_unittests.cc.

3334  {
3335  Canvas canvas;
3336  Paint paint;
3337  auto texture = CreateTextureForFixture("table_mountain_nx.png");
3338 
3339  paint.color_source = ColorSource::MakeImage(
3340  texture, Entity::TileMode::kClamp, Entity::TileMode::kClamp, {},
3341  Matrix::MakeTranslation({100.0, 100.0}));
3342 
3343  auto vertices = {Point(0, 0), Point(texture->GetSize().width, 0),
3344  Point(0, texture->GetSize().height)};
3345  std::vector<uint16_t> indices = {0u, 1u, 2u};
3346  std::vector<Point> texture_coordinates = {};
3347  std::vector<Color> vertex_colors = {};
3348  auto geometry = std::make_shared<VerticesGeometry>(
3349  vertices, indices, texture_coordinates, vertex_colors,
3350  Rect::MakeLTRB(0, 0, 1, 1), VerticesGeometry::VertexMode::kTriangleStrip);
3351 
3352  canvas.DrawVertices(geometry, BlendMode::kSourceOver, paint);
3353  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3354 }

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() [193/384]

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  auto src = context->GetResourceAllocator()->CreateTexture(src_desc);
28 
29  TextureDescriptor dst_format;
30  dst_format.format = PixelFormat::kR8G8B8A8UNormInt;
31  dst_format.size = {100, 100};
32  auto dst = context->GetResourceAllocator()->CreateTexture(dst_format);
33 
34  EXPECT_FALSE(blit_pass->AddCopy(src, dst));
35 }

References impeller::TextureDescriptor::format, impeller::kA8UNormInt, impeller::kR8G8B8A8UNormInt, and impeller::TextureDescriptor::size.

◆ TEST_P() [194/384]

impeller::testing::TEST_P ( BlitPassTest  ,
BlitAcrossDifferentSampleCountsFails   
)

Definition at line 37 of file blit_pass_unittests.cc.

37  {
38  ScopedValidationDisable scope; // avoid noise in output.
39  auto context = GetContext();
40  auto cmd_buffer = context->CreateCommandBuffer();
41  auto blit_pass = cmd_buffer->CreateBlitPass();
42 
43  TextureDescriptor src_desc;
44  src_desc.format = PixelFormat::kR8G8B8A8UNormInt;
45  src_desc.sample_count = SampleCount::kCount4;
46  src_desc.size = {100, 100};
47  auto src = context->GetResourceAllocator()->CreateTexture(src_desc);
48 
49  TextureDescriptor dst_format;
50  dst_format.format = PixelFormat::kR8G8B8A8UNormInt;
51  dst_format.size = {100, 100};
52  auto dst = context->GetResourceAllocator()->CreateTexture(dst_format);
53 
54  EXPECT_FALSE(blit_pass->AddCopy(src, dst));
55 }

References impeller::TextureDescriptor::format, impeller::kCount4, impeller::kR8G8B8A8UNormInt, impeller::TextureDescriptor::sample_count, and impeller::TextureDescriptor::size.

◆ TEST_P() [195/384]

impeller::testing::TEST_P ( BlitPassTest  ,
BlitPassesForMatchingFormats   
)

Definition at line 57 of file blit_pass_unittests.cc.

57  {
58  ScopedValidationDisable scope; // avoid noise in output.
59  auto context = GetContext();
60  auto cmd_buffer = context->CreateCommandBuffer();
61  auto blit_pass = cmd_buffer->CreateBlitPass();
62 
63  TextureDescriptor src_desc;
64  src_desc.format = PixelFormat::kR8G8B8A8UNormInt;
65  src_desc.size = {100, 100};
66  auto src = context->GetResourceAllocator()->CreateTexture(src_desc);
67 
68  TextureDescriptor dst_format;
69  dst_format.format = PixelFormat::kR8G8B8A8UNormInt;
70  dst_format.size = {100, 100};
71  auto dst = context->GetResourceAllocator()->CreateTexture(dst_format);
72 
73  EXPECT_TRUE(blit_pass->AddCopy(src, dst));
74 }

References impeller::TextureDescriptor::format, impeller::kR8G8B8A8UNormInt, and impeller::TextureDescriptor::size.

◆ TEST_P() [196/384]

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() [197/384]

impeller::testing::TEST_P ( ComputeSubgroupTest  ,
LargePath   
)

Definition at line 177 of file compute_subgroup_unittests.cc.

177  {
178  // The path in here is large enough to highlight issues around exceeding
179  // subgroup size.
180  using SS = StrokeComputeShader;
181 
182  auto context = GetContext();
183  ASSERT_TRUE(context);
184  ASSERT_TRUE(context->GetCapabilities()->SupportsComputeSubgroups());
185  size_t vertex_count = 0;
186  Scalar stroke_width = 1.0;
187 
188  auto vertex_buffer = CreateHostVisibleDeviceBuffer<SS::VertexBuffer<2048>>(
189  context, "VertexBuffer");
190  auto vertex_buffer_count =
191  CreateHostVisibleDeviceBuffer<SS::VertexBufferCount>(context,
192  "VertexCount");
193 
194  auto complex_path =
195  PathBuilder{}
196  .MoveTo({359.934, 96.6335})
197  .CubicCurveTo({358.189, 96.7055}, {356.436, 96.7908},
198  {354.673, 96.8895})
199  .CubicCurveTo({354.571, 96.8953}, {354.469, 96.9016},
200  {354.367, 96.9075})
201  .CubicCurveTo({352.672, 97.0038}, {350.969, 97.113},
202  {349.259, 97.2355})
203  .CubicCurveTo({349.048, 97.2506}, {348.836, 97.2678},
204  {348.625, 97.2834})
205  .CubicCurveTo({347.019, 97.4014}, {345.407, 97.5299},
206  {343.789, 97.6722})
207  .CubicCurveTo({343.428, 97.704}, {343.065, 97.7402},
208  {342.703, 97.7734})
209  .CubicCurveTo({341.221, 97.9086}, {339.736, 98.0505},
210  {338.246, 98.207})
211  .CubicCurveTo({337.702, 98.2642}, {337.156, 98.3292},
212  {336.612, 98.3894})
213  .CubicCurveTo({335.284, 98.5356}, {333.956, 98.6837},
214  {332.623, 98.8476})
215  .CubicCurveTo({332.495, 98.8635}, {332.366, 98.8818},
216  {332.237, 98.8982})
217  .LineTo({332.237, 102.601})
218  .LineTo({321.778, 102.601})
219  .LineTo({321.778, 100.382})
220  .CubicCurveTo({321.572, 100.413}, {321.367, 100.442},
221  {321.161, 100.476})
222  .CubicCurveTo({319.22, 100.79}, {317.277, 101.123},
223  {315.332, 101.479})
224  .CubicCurveTo({315.322, 101.481}, {315.311, 101.482},
225  {315.301, 101.484})
226  .LineTo({310.017, 105.94})
227  .LineTo({309.779, 105.427})
228  .LineTo({314.403, 101.651})
229  .CubicCurveTo({314.391, 101.653}, {314.379, 101.656},
230  {314.368, 101.658})
231  .CubicCurveTo({312.528, 102.001}, {310.687, 102.366},
232  {308.846, 102.748})
233  .CubicCurveTo({307.85, 102.955}, {306.855, 103.182}, {305.859, 103.4})
234  .CubicCurveTo({305.048, 103.579}, {304.236, 103.75},
235  {303.425, 103.936})
236  .LineTo({299.105, 107.578})
237  .LineTo({298.867, 107.065})
238  .LineTo({302.394, 104.185})
239  .LineTo({302.412, 104.171})
240  .CubicCurveTo({301.388, 104.409}, {300.366, 104.67},
241  {299.344, 104.921})
242  .CubicCurveTo({298.618, 105.1}, {297.89, 105.269}, {297.165, 105.455})
243  .CubicCurveTo({295.262, 105.94}, {293.36, 106.445},
244  {291.462, 106.979})
245  .CubicCurveTo({291.132, 107.072}, {290.802, 107.163},
246  {290.471, 107.257})
247  .CubicCurveTo({289.463, 107.544}, {288.455, 107.839},
248  {287.449, 108.139})
249  .CubicCurveTo({286.476, 108.431}, {285.506, 108.73},
250  {284.536, 109.035})
251  .CubicCurveTo({283.674, 109.304}, {282.812, 109.579},
252  {281.952, 109.859})
253  .CubicCurveTo({281.177, 110.112}, {280.406, 110.377},
254  {279.633, 110.638})
255  .CubicCurveTo({278.458, 111.037}, {277.256, 111.449},
256  {276.803, 111.607})
257  .CubicCurveTo({276.76, 111.622}, {276.716, 111.637},
258  {276.672, 111.653})
259  .CubicCurveTo({275.017, 112.239}, {273.365, 112.836},
260  {271.721, 113.463})
261  .LineTo({271.717, 113.449})
262  .CubicCurveTo({271.496, 113.496}, {271.238, 113.559},
263  {270.963, 113.628})
264  .CubicCurveTo({270.893, 113.645}, {270.822, 113.663},
265  {270.748, 113.682})
266  .CubicCurveTo({270.468, 113.755}, {270.169, 113.834},
267  {269.839, 113.926})
268  .CubicCurveTo({269.789, 113.94}, {269.732, 113.957},
269  {269.681, 113.972})
270  .CubicCurveTo({269.391, 114.053}, {269.081, 114.143},
271  {268.756, 114.239})
272  .CubicCurveTo({268.628, 114.276}, {268.5, 114.314},
273  {268.367, 114.354})
274  .CubicCurveTo({268.172, 114.412}, {267.959, 114.478},
275  {267.752, 114.54})
276  .CubicCurveTo({263.349, 115.964}, {258.058, 117.695},
277  {253.564, 119.252})
278  .CubicCurveTo({253.556, 119.255}, {253.547, 119.258},
279  {253.538, 119.261})
280  .CubicCurveTo({251.844, 119.849}, {250.056, 120.474},
281  {248.189, 121.131})
282  .CubicCurveTo({248, 121.197}, {247.812, 121.264}, {247.621, 121.331})
283  .CubicCurveTo({247.079, 121.522}, {246.531, 121.715},
284  {245.975, 121.912})
285  .CubicCurveTo({245.554, 122.06}, {245.126, 122.212},
286  {244.698, 122.364})
287  .CubicCurveTo({244.071, 122.586}, {243.437, 122.811},
288  {242.794, 123.04})
289  .CubicCurveTo({242.189, 123.255}, {241.58, 123.472},
290  {240.961, 123.693})
291  .CubicCurveTo({240.659, 123.801}, {240.357, 123.909},
292  {240.052, 124.018})
293  .CubicCurveTo({239.12, 124.351}, {238.18, 124.687}, {237.22, 125.032})
294  .LineTo({237.164, 125.003})
295  .CubicCurveTo({236.709, 125.184}, {236.262, 125.358},
296  {235.81, 125.538})
297  .CubicCurveTo({235.413, 125.68}, {234.994, 125.832},
298  {234.592, 125.977})
299  .CubicCurveTo({234.592, 125.977}, {234.591, 125.977},
300  {234.59, 125.977})
301  .CubicCurveTo({222.206, 130.435}, {207.708, 135.753},
302  {192.381, 141.429})
303  .CubicCurveTo({162.77, 151.336}, {122.17, 156.894}, {84.1123, 160})
304  .LineTo({360, 160})
305  .LineTo({360, 119.256})
306  .LineTo({360, 106.332})
307  .LineTo({360, 96.6307})
308  .CubicCurveTo({359.978, 96.6317}, {359.956, 96.6326},
309  {359.934, 96.6335})
310  .Close()
311  .TakePath();
312 
313  auto callback = [&](RenderPass& pass) -> bool {
314  ::memset(vertex_buffer_count->AsBufferView().contents, 0,
315  sizeof(SS::VertexBufferCount));
316  ::memset(vertex_buffer->AsBufferView().contents, 0,
317  sizeof(SS::VertexBuffer<2048>));
318 
319  ComputeTessellator{}
320  .SetStrokeWidth(stroke_width)
321  .Tessellate(
322  complex_path, context, vertex_buffer->AsBufferView(),
323  vertex_buffer_count->AsBufferView(),
324  [vertex_buffer_count, &vertex_count](CommandBuffer::Status status) {
325  vertex_count = reinterpret_cast<SS::VertexBufferCount*>(
326  vertex_buffer_count->AsBufferView().contents)
327  ->count;
328  });
329 
330  ContentContext renderer(context, nullptr);
331  if (!renderer.IsValid()) {
332  return false;
333  }
334 
335  using VS = SolidFillPipeline::VertexShader;
336 
337  Command cmd;
338  DEBUG_COMMAND_INFO(cmd, "Draw Stroke");
339  cmd.stencil_reference = 0;
340 
341  ContentContextOptions options;
342  options.sample_count = pass.GetRenderTarget().GetSampleCount();
343  options.color_attachment_pixel_format =
344  pass.GetRenderTarget().GetRenderTargetPixelFormat();
345  options.has_stencil_attachment =
346  pass.GetRenderTarget().GetStencilAttachment().has_value();
347  options.blend_mode = BlendMode::kSourceIn;
348  options.primitive_type = PrimitiveType::kTriangleStrip;
349  options.stencil_compare = CompareFunction::kEqual;
350  options.stencil_operation = StencilOperation::kIncrementClamp;
351 
352  cmd.pipeline = renderer.GetSolidFillPipeline(options);
353 
354  auto count = reinterpret_cast<SS::VertexBufferCount*>(
355  vertex_buffer_count->AsBufferView().contents)
356  ->count;
357 
358  cmd.BindVertices(
359  VertexBuffer{.vertex_buffer = vertex_buffer->AsBufferView(),
360  .vertex_count = count,
361  .index_type = IndexType::kNone});
362 
363  VS::FrameInfo frame_info;
364  auto world_matrix = Matrix::MakeScale(GetContentScale());
365  frame_info.mvp = pass.GetOrthographicTransform() * world_matrix;
366  frame_info.color = Color::Red().Premultiply();
367  VS::BindFrameInfo(cmd,
368  pass.GetTransientsBuffer().EmplaceUniform(frame_info));
369 
370  if (!pass.AddCommand(std::move(cmd))) {
371  return false;
372  }
373 
374  return true;
375  };
376  ASSERT_TRUE(OpenPlaygroundHere(callback));
377 }

References impeller::Command::BindVertices(), impeller::ContentContextOptions::blend_mode, impeller::Close(), impeller::ContentContextOptions::color_attachment_pixel_format, DEBUG_COMMAND_INFO, impeller::ContentContext::GetSolidFillPipeline(), impeller::ContentContextOptions::has_stencil_attachment, impeller::ContentContext::IsValid(), impeller::kEqual, impeller::kIncrementClamp, impeller::kNone, impeller::kSourceIn, impeller::kTriangleStrip, impeller::LineTo(), impeller::Matrix::MakeScale(), impeller::PathBuilder::MoveTo(), impeller::Command::pipeline, impeller::Color::Premultiply(), impeller::ContentContextOptions::primitive_type, impeller::Color::Red(), impeller::ContentContextOptions::sample_count, impeller::ComputeTessellator::SetStrokeWidth(), impeller::ContentContextOptions::stencil_compare, impeller::ContentContextOptions::stencil_operation, impeller::Command::stencil_reference, impeller::ComputeTessellator::Tessellate(), and impeller::VertexBuffer::vertex_buffer.

◆ TEST_P() [198/384]

impeller::testing::TEST_P ( ComputeSubgroupTest  ,
PathPlayground   
)

Definition at line 48 of file compute_subgroup_unittests.cc.

48  {
49  // Renders stroked SVG paths in an interactive playground.
50  using SS = StrokeComputeShader;
51 
52  auto context = GetContext();
53  ASSERT_TRUE(context);
54  ASSERT_TRUE(context->GetCapabilities()->SupportsComputeSubgroups());
55  char svg_path_data[16384] =
56  "M140 20 "
57  "C73 20 20 74 20 140 "
58  "c0 135 136 170 228 303 "
59  "88-132 229-173 229-303 "
60  "0-66-54-120-120-120 "
61  "-48 0-90 28-109 69 "
62  "-19-41-60-69-108-69z";
63  size_t vertex_count = 0;
64  Scalar stroke_width = 1.0;
65 
66  auto vertex_buffer = CreateHostVisibleDeviceBuffer<SS::VertexBuffer<2048>>(
67  context, "VertexBuffer");
68  auto vertex_buffer_count =
69  CreateHostVisibleDeviceBuffer<SS::VertexBufferCount>(context,
70  "VertexCount");
71 
72  auto callback = [&](RenderPass& pass) -> bool {
73  ::memset(vertex_buffer_count->AsBufferView().contents, 0,
74  sizeof(SS::VertexBufferCount));
75  ::memset(vertex_buffer->AsBufferView().contents, 0,
76  sizeof(SS::VertexBuffer<2048>));
77  const auto* main_viewport = ImGui::GetMainViewport();
78  ImGui::SetNextWindowPos(
79  ImVec2(main_viewport->WorkPos.x + 650, main_viewport->WorkPos.y + 20));
80  ImGui::Begin("Path data", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
81  ImGui::InputTextMultiline("Path", svg_path_data,
82  IM_ARRAYSIZE(svg_path_data));
83  ImGui::DragFloat("Stroke width", &stroke_width, .1, 0.0, 25.0);
84 
85  SkPath sk_path;
86  if (SkParsePath::FromSVGString(svg_path_data, &sk_path)) {
87  std::promise<bool> promise;
88  auto future = promise.get_future();
89 
90  auto path = skia_conversions::ToPath(sk_path);
91  auto status =
92  ComputeTessellator{}
93  .SetStrokeWidth(stroke_width)
94  .Tessellate(
95  path, context, vertex_buffer->AsBufferView(),
96  vertex_buffer_count->AsBufferView(),
97  [vertex_buffer_count, &vertex_count,
98  &promise](CommandBuffer::Status status) {
99  vertex_count =
100  reinterpret_cast<SS::VertexBufferCount*>(
101  vertex_buffer_count->AsBufferView().contents)
102  ->count;
103  promise.set_value(status ==
104  CommandBuffer::Status::kCompleted);
105  });
106  switch (status) {
107  case ComputeTessellator::Status::kCommandInvalid:
108  ImGui::Text("Failed to submit compute job (invalid command)");
109  break;
110  case ComputeTessellator::Status::kTooManyComponents:
111  ImGui::Text("Failed to submit compute job (too many components) ");
112  break;
113  case ComputeTessellator::Status::kOk:
114  break;
115  }
116  if (!future.get()) {
117  ImGui::Text("Failed to submit compute job.");
118  return false;
119  }
120  if (vertex_count > 0) {
121  ImGui::Text("Vertex count: %zu", vertex_count);
122  }
123  } else {
124  ImGui::Text("Failed to parse path data");
125  }
126  ImGui::End();
127 
128  ContentContext renderer(context, nullptr);
129  if (!renderer.IsValid()) {
130  return false;
131  }
132 
133  using VS = SolidFillPipeline::VertexShader;
134 
135  Command cmd;
136  DEBUG_COMMAND_INFO(cmd, "Draw Stroke");
137  cmd.stencil_reference = 0;
138 
139  ContentContextOptions options;
140  options.sample_count = pass.GetRenderTarget().GetSampleCount();
141  options.color_attachment_pixel_format =
142  pass.GetRenderTarget().GetRenderTargetPixelFormat();
143  options.has_stencil_attachment =
144  pass.GetRenderTarget().GetStencilAttachment().has_value();
145  options.blend_mode = BlendMode::kSourceIn;
146  options.primitive_type = PrimitiveType::kTriangleStrip;
147  options.stencil_compare = CompareFunction::kEqual;
148  options.stencil_operation = StencilOperation::kIncrementClamp;
149 
150  cmd.pipeline = renderer.GetSolidFillPipeline(options);
151 
152  auto count = reinterpret_cast<SS::VertexBufferCount*>(
153  vertex_buffer_count->AsBufferView().contents)
154  ->count;
155 
156  cmd.BindVertices(
157  VertexBuffer{.vertex_buffer = vertex_buffer->AsBufferView(),
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(cmd,
166  pass.GetTransientsBuffer().EmplaceUniform(frame_info));
167 
168  if (!pass.AddCommand(std::move(cmd))) {
169  return false;
170  }
171 
172  return true;
173  };
174  ASSERT_TRUE(OpenPlaygroundHere(callback));
175 }

References impeller::Command::BindVertices(), impeller::ContentContextOptions::blend_mode, impeller::ContentContextOptions::color_attachment_pixel_format, DEBUG_COMMAND_INFO, impeller::ContentContext::GetSolidFillPipeline(), impeller::ContentContextOptions::has_stencil_attachment, impeller::ContentContext::IsValid(), impeller::ComputeTessellator::kCommandInvalid, impeller::kEqual, impeller::kIncrementClamp, impeller::kNone, impeller::ComputeTessellator::kOk, impeller::kSourceIn, impeller::ComputeTessellator::kTooManyComponents, impeller::kTriangleStrip, impeller::Matrix::MakeScale(), impeller::Command::pipeline, impeller::Color::Premultiply(), impeller::ContentContextOptions::primitive_type, impeller::Color::Red(), impeller::ContentContextOptions::sample_count, impeller::ComputeTessellator::SetStrokeWidth(), impeller::ContentContextOptions::stencil_compare, impeller::ContentContextOptions::stencil_operation, impeller::Command::stencil_reference, impeller::ComputeTessellator::Tessellate(), impeller::skia_conversions::ToPath(), and impeller::VertexBuffer::vertex_buffer.

◆ TEST_P() [199/384]

impeller::testing::TEST_P ( ComputeSubgroupTest  ,
QuadAndCubicInOnePath   
)

Definition at line 379 of file compute_subgroup_unittests.cc.

379  {
380  using SS = StrokeComputeShader;
381 
382  auto context = GetContext();
383  ASSERT_TRUE(context);
384  ASSERT_TRUE(context->GetCapabilities()->SupportsComputeSubgroups());
385 
386  auto vertex_buffer = CreateHostVisibleDeviceBuffer<SS::VertexBuffer<2048>>(
387  context, "VertexBuffer");
388  auto vertex_buffer_count =
389  CreateHostVisibleDeviceBuffer<SS::VertexBufferCount>(context,
390  "VertexBufferCount");
391 
392  auto path = PathBuilder{}
393  .AddCubicCurve({140, 20}, {73, 20}, {20, 74}, {20, 140})
394  .AddQuadraticCurve({20, 140}, {93, 90}, {100, 42})
395  .TakePath();
396 
397  auto tessellator = ComputeTessellator{};
398 
399  fml::AutoResetWaitableEvent latch;
400 
401  auto status = tessellator.Tessellate(
402  path, context, vertex_buffer->AsBufferView(),
403  vertex_buffer_count->AsBufferView(),
404  [&latch](CommandBuffer::Status status) {
405  EXPECT_EQ(status, CommandBuffer::Status::kCompleted);
406  latch.Signal();
407  });
408 
409  ASSERT_EQ(status, ComputeTessellator::Status::kOk);
410 
411  auto callback = [&](RenderPass& pass) -> bool {
412  ContentContext renderer(context, nullptr);
413  if (!renderer.IsValid()) {
414  return false;
415  }
416 
417  using VS = SolidFillPipeline::VertexShader;
418 
419  Command cmd;
420  DEBUG_COMMAND_INFO(cmd, "Draw Stroke");
421  cmd.stencil_reference = 0;
422 
423  ContentContextOptions options;
424  options.sample_count = pass.GetRenderTarget().GetSampleCount();
425  options.color_attachment_pixel_format =
426  pass.GetRenderTarget().GetRenderTargetPixelFormat();
427  options.has_stencil_attachment =
428  pass.GetRenderTarget().GetStencilAttachment().has_value();
429  options.blend_mode = BlendMode::kSourceIn;
430  options.primitive_type = PrimitiveType::kTriangleStrip;
431  options.stencil_compare = CompareFunction::kEqual;
432  options.stencil_operation = StencilOperation::kIncrementClamp;
433 
434  cmd.pipeline = renderer.GetSolidFillPipeline(options);
435 
436  auto count = reinterpret_cast<SS::VertexBufferCount*>(
437  vertex_buffer_count->AsBufferView().contents)
438  ->count;
439 
440  cmd.BindVertices(
441  VertexBuffer{.vertex_buffer = vertex_buffer->AsBufferView(),
442  .vertex_count = count,
443  .index_type = IndexType::kNone});
444 
445  VS::FrameInfo frame_info;
446  auto world_matrix = Matrix::MakeScale(GetContentScale());
447  frame_info.mvp = pass.GetOrthographicTransform() * world_matrix;
448  frame_info.color = Color::Red().Premultiply();
449  VS::BindFrameInfo(cmd,
450  pass.GetTransientsBuffer().EmplaceUniform(frame_info));
451 
452  if (!pass.AddCommand(std::move(cmd))) {
453  return false;
454  }
455 
456  return true;
457  };
458  ASSERT_TRUE(OpenPlaygroundHere(callback));
459 
460  // The latch is down here because it's expected that on Metal the backend
461  // will take care of synchronizing the buffer between the compute and render
462  // pass usages, since it's not MTLHeap allocated. However, if playgrounds
463  // are disabled, no render pass actually gets submitted and we need to do a
464  // CPU latch here.
465  latch.Wait();
466 
467  auto vertex_count = reinterpret_cast<SS::VertexBufferCount*>(
468  vertex_buffer_count->AsBufferView().contents)
469  ->count;
470  EXPECT_EQ(vertex_count, golden_cubic_and_quad_points.size());
471  auto vertex_buffer_data = reinterpret_cast<SS::VertexBuffer<2048>*>(
472  vertex_buffer->AsBufferView().contents);
473  for (size_t i = 0; i < vertex_count; i++) {
474  EXPECT_LT(std::abs(golden_cubic_and_quad_points[i].x -
475  vertex_buffer_data->position[i].x),
476  1e-3);
477  EXPECT_LT(std::abs(golden_cubic_and_quad_points[i].y -
478  vertex_buffer_data->position[i].y),
479  1e-3);
480  }
481 }

References impeller::PathBuilder::AddCubicCurve(), impeller::Command::BindVertices(), impeller::ContentContextOptions::blend_mode, impeller::ContentContextOptions::color_attachment_pixel_format, DEBUG_COMMAND_INFO, impeller::ContentContext::GetSolidFillPipeline(), golden_cubic_and_quad_points, impeller::ContentContextOptions::has_stencil_attachment, impeller::ContentContext::IsValid(), impeller::kEqual, impeller::kIncrementClamp, impeller::kNone, impeller::ComputeTessellator::kOk, impeller::kSourceIn, impeller::kTriangleStrip, impeller::Matrix::MakeScale(), impeller::Command::pipeline, impeller::Color::Premultiply(), impeller::ContentContextOptions::primitive_type, impeller::Color::Red(), impeller::ContentContextOptions::sample_count, impeller::ContentContextOptions::stencil_compare, impeller::ContentContextOptions::stencil_operation, impeller::Command::stencil_reference, impeller::ComputeTessellator::Tessellate(), and impeller::VertexBuffer::vertex_buffer.

◆ TEST_P() [200/384]

impeller::testing::TEST_P ( ComputeTest  ,
1DThreadgroupSizingIsCorrect   
)

Definition at line 178 of file compute_unittests.cc.

178  {
179  using CS = ThreadgroupSizingTestComputeShader;
180  auto context = GetContext();
181  ASSERT_TRUE(context);
182  ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
183 
184  using SamplePipelineBuilder = ComputePipelineBuilder<CS>;
185  auto pipeline_desc =
186  SamplePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
187  ASSERT_TRUE(pipeline_desc.has_value());
188  auto compute_pipeline =
189  context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
190  ASSERT_TRUE(compute_pipeline);
191 
192  auto cmd_buffer = context->CreateCommandBuffer();
193  auto pass = cmd_buffer->CreateComputePass();
194  ASSERT_TRUE(pass && pass->IsValid());
195 
196  static constexpr size_t kCount = 2048;
197 
198  pass->SetGridSize(ISize(kCount, 1));
199  pass->SetThreadGroupSize(ISize(kCount, 1));
200 
201  ComputeCommand cmd;
202  cmd.pipeline = compute_pipeline;
203 
204  auto output_buffer = CreateHostVisibleDeviceBuffer<CS::OutputData<kCount>>(
205  context, "Output Buffer");
206 
207  CS::BindOutputData(cmd, output_buffer->AsBufferView());
208 
209  ASSERT_TRUE(pass->AddCommand(std::move(cmd)));
210  ASSERT_TRUE(pass->EncodeCommands());
211 
212  fml::AutoResetWaitableEvent latch;
213  ASSERT_TRUE(cmd_buffer->SubmitCommands(
214  [&latch, output_buffer](CommandBuffer::Status status) {
215  EXPECT_EQ(status, CommandBuffer::Status::kCompleted);
216 
217  auto view = output_buffer->AsBufferView();
218  EXPECT_EQ(view.range.length, sizeof(CS::OutputData<kCount>));
219 
220  CS::OutputData<kCount>* output =
221  reinterpret_cast<CS::OutputData<kCount>*>(view.contents);
222  EXPECT_TRUE(output);
223  EXPECT_EQ(output->data[kCount - 1], kCount - 1);
224  latch.Signal();
225  }));
226 
227  latch.Wait();
228 }

References impeller::ComputeCommand::pipeline.

◆ TEST_P() [201/384]

impeller::testing::TEST_P ( ComputeTest  ,
CanCompute1DimensionalData   
)

Definition at line 373 of file compute_unittests.cc.

373  {
374  using CS = SampleComputeShader;
375  auto context = GetContext();
376  ASSERT_TRUE(context);
377  ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
378 
379  using SamplePipelineBuilder = ComputePipelineBuilder<CS>;
380  auto pipeline_desc =
381  SamplePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
382  ASSERT_TRUE(pipeline_desc.has_value());
383  auto compute_pipeline =
384  context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
385  ASSERT_TRUE(compute_pipeline);
386 
387  auto cmd_buffer = context->CreateCommandBuffer();
388  auto pass = cmd_buffer->CreateComputePass();
389  ASSERT_TRUE(pass && pass->IsValid());
390 
391  static constexpr size_t kCount = 5;
392 
393  pass->SetGridSize(ISize(kCount, 1));
394 
395  ComputeCommand cmd;
396  cmd.pipeline = compute_pipeline;
397 
398  CS::Info info{.count = kCount};
399  CS::Input0<kCount> input_0;
400  CS::Input1<kCount> input_1;
401  for (size_t i = 0; i < kCount; i++) {
402  input_0.elements[i] = Vector4(2.0 + i, 3.0 + i, 4.0 + i, 5.0 * i);
403  input_1.elements[i] = Vector4(6.0, 7.0, 8.0, 9.0);
404  }
405 
406  input_0.fixed_array[1] = IPoint32(2, 2);
407  input_1.fixed_array[0] = UintPoint32(3, 3);
408  input_0.some_int = 5;
409  input_1.some_struct = CS::SomeStruct{.vf = Point(3, 4), .i = 42};
410 
411  auto output_buffer = CreateHostVisibleDeviceBuffer<CS::Output<kCount>>(
412  context, "Output Buffer");
413 
414  CS::BindInfo(cmd, pass->GetTransientsBuffer().EmplaceUniform(info));
415  CS::BindInput0(cmd,
416  pass->GetTransientsBuffer().EmplaceStorageBuffer(input_0));
417  CS::BindInput1(cmd,
418  pass->GetTransientsBuffer().EmplaceStorageBuffer(input_1));
419  CS::BindOutput(cmd, output_buffer->AsBufferView());
420 
421  ASSERT_TRUE(pass->AddCommand(std::move(cmd)));
422  ASSERT_TRUE(pass->EncodeCommands());
423 
424  fml::AutoResetWaitableEvent latch;
425  ASSERT_TRUE(
426  cmd_buffer->SubmitCommands([&latch, output_buffer, &input_0,
427  &input_1](CommandBuffer::Status status) {
428  EXPECT_EQ(status, CommandBuffer::Status::kCompleted);
429 
430  auto view = output_buffer->AsBufferView();
431  EXPECT_EQ(view.range.length, sizeof(CS::Output<kCount>));
432 
433  CS::Output<kCount>* output =
434  reinterpret_cast<CS::Output<kCount>*>(view.contents);
435  EXPECT_TRUE(output);
436  for (size_t i = 0; i < kCount; i++) {
437  Vector4 vector = output->elements[i];
438  Vector4 computed = input_0.elements[i] * input_1.elements[i];
439  EXPECT_EQ(vector, Vector4(computed.x + 2 + input_1.some_struct.i,
440  computed.y + 3 + input_1.some_struct.vf.x,
441  computed.z + 5 + input_1.some_struct.vf.y,
442  computed.w));
443  }
444  latch.Signal();
445  }));
446 
447  latch.Wait();
448 }

References impeller::ComputeCommand::pipeline.

◆ TEST_P() [202/384]

impeller::testing::TEST_P ( ComputeTest  ,
CanComputePrefixSum   
)

Definition at line 113 of file compute_unittests.cc.

113  {
114  using CS = PrefixSumTestComputeShader;
115  auto context = GetContext();
116  ASSERT_TRUE(context);
117  ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
118 
119  using SamplePipelineBuilder = ComputePipelineBuilder<CS>;
120  auto pipeline_desc =
121  SamplePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
122  ASSERT_TRUE(pipeline_desc.has_value());
123  auto compute_pipeline =
124  context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
125  ASSERT_TRUE(compute_pipeline);
126 
127  auto cmd_buffer = context->CreateCommandBuffer();
128  auto pass = cmd_buffer->CreateComputePass();
129  ASSERT_TRUE(pass && pass->IsValid());
130 
131  static constexpr size_t kCount = 5;
132 
133  pass->SetGridSize(ISize(kCount, 1));
134  pass->SetThreadGroupSize(ISize(kCount, 1));
135 
136  ComputeCommand cmd;
137  cmd.pipeline = compute_pipeline;
138 
139  CS::InputData<kCount> input_data;
140  input_data.count = kCount;
141  for (size_t i = 0; i < kCount; i++) {
142  input_data.data[i] = 1 + i;
143  }
144 
145  auto output_buffer = CreateHostVisibleDeviceBuffer<CS::OutputData<kCount>>(
146  context, "Output Buffer");
147 
148  CS::BindInputData(
149  cmd, pass->GetTransientsBuffer().EmplaceStorageBuffer(input_data));
150  CS::BindOutputData(cmd, output_buffer->AsBufferView());
151 
152  ASSERT_TRUE(pass->AddCommand(std::move(cmd)));
153  ASSERT_TRUE(pass->EncodeCommands());
154 
155  fml::AutoResetWaitableEvent latch;
156  ASSERT_TRUE(cmd_buffer->SubmitCommands(
157  [&latch, output_buffer](CommandBuffer::Status status) {
158  EXPECT_EQ(status, CommandBuffer::Status::kCompleted);
159 
160  auto view = output_buffer->AsBufferView();
161  EXPECT_EQ(view.range.length, sizeof(CS::OutputData<kCount>));
162 
163  CS::OutputData<kCount>* output =
164  reinterpret_cast<CS::OutputData<kCount>*>(view.contents);
165  EXPECT_TRUE(output);
166 
167  constexpr uint32_t expected[kCount] = {1, 3, 6, 10, 15};
168  for (size_t i = 0; i < kCount; i++) {
169  auto computed_sum = output->data[i];
170  EXPECT_EQ(computed_sum, expected[i]);
171  }
172  latch.Signal();
173  }));
174 
175  latch.Wait();
176 }

References impeller::ComputeCommand::pipeline.

◆ TEST_P() [203/384]

impeller::testing::TEST_P ( ComputeTest  ,
CanComputePrefixSumLargeInteractive   
)

Definition at line 230 of file compute_unittests.cc.

230  {
231  using CS = PrefixSumTestComputeShader;
232 
233  auto context = GetContext();
234  ASSERT_TRUE(context);
235  ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
236 
237  auto callback = [&](RenderPass& render_pass) -> bool {
238  using SamplePipelineBuilder = ComputePipelineBuilder<CS>;
239  auto pipeline_desc =
240  SamplePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
241  auto compute_pipeline =
242  context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
243 
244  auto cmd_buffer = context->CreateCommandBuffer();
245  auto pass = cmd_buffer->CreateComputePass();
246 
247  static constexpr size_t kCount = 1023;
248 
249  pass->SetGridSize(ISize(kCount, 1));
250 
251  ComputeCommand cmd;
252  cmd.pipeline = compute_pipeline;
253 
254  CS::InputData<kCount> input_data;
255  input_data.count = kCount;
256  for (size_t i = 0; i < kCount; i++) {
257  input_data.data[i] = 1 + i;
258  }
259 
260  auto output_buffer = CreateHostVisibleDeviceBuffer<CS::OutputData<kCount>>(
261  context, "Output Buffer");
262 
263  CS::BindInputData(
264  cmd, pass->GetTransientsBuffer().EmplaceStorageBuffer(input_data));
265  CS::BindOutputData(cmd, output_buffer->AsBufferView());
266 
267  pass->AddCommand(std::move(cmd));
268  pass->EncodeCommands();
269  return cmd_buffer->SubmitCommands();
270  };
271  ASSERT_TRUE(OpenPlaygroundHere(callback));
272 }

References impeller::ComputeCommand::pipeline.

◆ TEST_P() [204/384]

impeller::testing::TEST_P ( ComputeTest  ,
CanCreateComputePass   
)

Definition at line 35 of file compute_unittests.cc.

35  {
36  using CS = SampleComputeShader;
37  auto context = GetContext();
38  ASSERT_TRUE(context);
39  ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
40 
41  using SamplePipelineBuilder = ComputePipelineBuilder<CS>;
42  auto pipeline_desc =
43  SamplePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
44  ASSERT_TRUE(pipeline_desc.has_value());
45  auto compute_pipeline =
46  context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
47  ASSERT_TRUE(compute_pipeline);
48 
49  auto cmd_buffer = context->CreateCommandBuffer();
50  auto pass = cmd_buffer->CreateComputePass();
51  ASSERT_TRUE(pass && pass->IsValid());
52 
53  static constexpr size_t kCount = 5;
54 
55  pass->SetGridSize(ISize(kCount, 1));
56  pass->SetThreadGroupSize(ISize(kCount, 1));
57 
58  ComputeCommand cmd;
59  cmd.pipeline = compute_pipeline;
60 
61  CS::Info info{.count = kCount};
62  CS::Input0<kCount> input_0;
63  CS::Input1<kCount> input_1;
64  for (size_t i = 0; i < kCount; i++) {
65  input_0.elements[i] = Vector4(2.0 + i, 3.0 + i, 4.0 + i, 5.0 * i);
66  input_1.elements[i] = Vector4(6.0, 7.0, 8.0, 9.0);
67  }
68 
69  input_0.fixed_array[1] = IPoint32(2, 2);
70  input_1.fixed_array[0] = UintPoint32(3, 3);
71  input_0.some_int = 5;
72  input_1.some_struct = CS::SomeStruct{.vf = Point(3, 4), .i = 42};
73 
74  auto output_buffer = CreateHostVisibleDeviceBuffer<CS::Output<kCount>>(
75  context, "Output Buffer");
76 
77  CS::BindInfo(cmd, pass->GetTransientsBuffer().EmplaceUniform(info));
78  CS::BindInput0(cmd,
79  pass->GetTransientsBuffer().EmplaceStorageBuffer(input_0));
80  CS::BindInput1(cmd,
81  pass->GetTransientsBuffer().EmplaceStorageBuffer(input_1));
82  CS::BindOutput(cmd, output_buffer->AsBufferView());
83 
84  ASSERT_TRUE(pass->AddCommand(std::move(cmd)));
85  ASSERT_TRUE(pass->EncodeCommands());
86 
87  fml::AutoResetWaitableEvent latch;
88  ASSERT_TRUE(
89  cmd_buffer->SubmitCommands([&latch, output_buffer, &input_0,
90  &input_1](CommandBuffer::Status status) {
91  EXPECT_EQ(status, CommandBuffer::Status::kCompleted);
92 
93  auto view = output_buffer->AsBufferView();
94  EXPECT_EQ(view.range.length, sizeof(CS::Output<kCount>));
95 
96  CS::Output<kCount>* output =
97  reinterpret_cast<CS::Output<kCount>*>(view.contents);
98  EXPECT_TRUE(output);
99  for (size_t i = 0; i < kCount; i++) {
100  Vector4 vector = output->elements[i];
101  Vector4 computed = input_0.elements[i] * input_1.elements[i];
102  EXPECT_EQ(vector, Vector4(computed.x + 2 + input_1.some_struct.i,
103  computed.y + 3 + input_1.some_struct.vf.x,
104  computed.z + 5 + input_1.some_struct.vf.y,
105  computed.w));
106  }
107  latch.Signal();
108  }));
109 
110  latch.Wait();
111 }

References impeller::ComputeCommand::pipeline.

◆ TEST_P() [205/384]

impeller::testing::TEST_P ( ComputeTest  ,
CapabilitiesReportSupport   
)

Definition at line 29 of file compute_unittests.cc.

29  {
30  auto context = GetContext();
31  ASSERT_TRUE(context);
32  ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
33 }

◆ TEST_P() [206/384]

impeller::testing::TEST_P ( ComputeTest  ,
MultiStageInputAndOutput   
)

Definition at line 274 of file compute_unittests.cc.

274  {
275  using CS1 = Stage1ComputeShader;
276  using Stage1PipelineBuilder = ComputePipelineBuilder<CS1>;
277  using CS2 = Stage2ComputeShader;
278  using Stage2PipelineBuilder = ComputePipelineBuilder<CS2>;
279 
280  auto context = GetContext();
281  ASSERT_TRUE(context);
282  ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
283 
284  auto pipeline_desc_1 =
285  Stage1PipelineBuilder::MakeDefaultPipelineDescriptor(*context);
286  ASSERT_TRUE(pipeline_desc_1.has_value());
287  auto compute_pipeline_1 =
288  context->GetPipelineLibrary()->GetPipeline(pipeline_desc_1).Get();
289  ASSERT_TRUE(compute_pipeline_1);
290 
291  auto pipeline_desc_2 =
292  Stage2PipelineBuilder::MakeDefaultPipelineDescriptor(*context);
293  ASSERT_TRUE(pipeline_desc_2.has_value());
294  auto compute_pipeline_2 =
295  context->GetPipelineLibrary()->GetPipeline(pipeline_desc_2).Get();
296  ASSERT_TRUE(compute_pipeline_2);
297 
298  auto cmd_buffer = context->CreateCommandBuffer();
299  auto pass = cmd_buffer->CreateComputePass();
300  ASSERT_TRUE(pass && pass->IsValid());
301 
302  static constexpr size_t kCount1 = 5;
303  static constexpr size_t kCount2 = kCount1 * 2;
304 
305  pass->SetGridSize(ISize(512, 1));
306  pass->SetThreadGroupSize(ISize(512, 1));
307 
308  CS1::Input<kCount1> input_1;
309  input_1.count = kCount1;
310  for (size_t i = 0; i < kCount1; i++) {
311  input_1.elements[i] = i;
312  }
313 
314  CS2::Input<kCount2> input_2;
315  input_2.count = kCount2;
316  for (size_t i = 0; i < kCount2; i++) {
317  input_2.elements[i] = i;
318  }
319 
320  auto output_buffer_1 = CreateHostVisibleDeviceBuffer<CS1::Output<kCount2>>(
321  context, "Output Buffer Stage 1");
322  auto output_buffer_2 = CreateHostVisibleDeviceBuffer<CS2::Output<kCount2>>(
323  context, "Output Buffer Stage 2");
324 
325  {
326  ComputeCommand cmd;
327  cmd.pipeline = compute_pipeline_1;
328 
329  CS1::BindInput(cmd,
330  pass->GetTransientsBuffer().EmplaceStorageBuffer(input_1));
331  CS1::BindOutput(cmd, output_buffer_1->AsBufferView());
332 
333  ASSERT_TRUE(pass->AddCommand(std::move(cmd)));
334  }
335 
336  {
337  ComputeCommand cmd;
338  cmd.pipeline = compute_pipeline_2;
339 
340  CS1::BindInput(cmd, output_buffer_1->AsBufferView());
341  CS2::BindOutput(cmd, output_buffer_2->AsBufferView());
342  ASSERT_TRUE(pass->AddCommand(std::move(cmd)));
343  }
344 
345  ASSERT_TRUE(pass->EncodeCommands());
346 
347  fml::AutoResetWaitableEvent latch;
348  ASSERT_TRUE(cmd_buffer->SubmitCommands([&latch, &output_buffer_1,
349  &output_buffer_2](
350  CommandBuffer::Status status) {
351  EXPECT_EQ(status, CommandBuffer::Status::kCompleted);
352 
353  CS1::Output<kCount2>* output_1 = reinterpret_cast<CS1::Output<kCount2>*>(
354  output_buffer_1->AsBufferView().contents);
355  EXPECT_TRUE(output_1);
356  EXPECT_EQ(output_1->count, 10u);
357  EXPECT_THAT(output_1->elements,
358  ::testing::ElementsAre(0, 0, 2, 3, 4, 6, 6, 9, 8, 12));
359 
360  CS2::Output<kCount2>* output_2 = reinterpret_cast<CS2::Output<kCount2>*>(
361  output_buffer_2->AsBufferView().contents);
362  EXPECT_TRUE(output_2);
363  EXPECT_EQ(output_2->count, 10u);
364  EXPECT_THAT(output_2->elements,
365  ::testing::ElementsAre(0, 0, 4, 6, 8, 12, 12, 18, 16, 24));
366 
367  latch.Signal();
368  }));
369 
370  latch.Wait();
371 }

References impeller::kCount1, and impeller::ComputeCommand::pipeline.

◆ TEST_P() [207/384]

impeller::testing::TEST_P ( ComputeTest  ,
ReturnsEarlyWhenAnyGridDimensionIsZero   
)

Definition at line 450 of file compute_unittests.cc.

450  {
451  using CS = SampleComputeShader;
452  auto context = GetContext();
453  ASSERT_TRUE(context);
454  ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
455 
456  using SamplePipelineBuilder = ComputePipelineBuilder<CS>;
457  auto pipeline_desc =
458  SamplePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
459  ASSERT_TRUE(pipeline_desc.has_value());
460  auto compute_pipeline =
461  context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
462  ASSERT_TRUE(compute_pipeline);
463 
464  auto cmd_buffer = context->CreateCommandBuffer();
465  auto pass = cmd_buffer->CreateComputePass();
466  ASSERT_TRUE(pass && pass->IsValid());
467 
468  static constexpr size_t kCount = 5;
469 
470  // Intentionally making the grid size zero in one dimension. No GPU will
471  // tolerate this.
472  pass->SetGridSize(ISize(0, 1));
473  pass->SetThreadGroupSize(ISize(0, 1));
474 
475  ComputeCommand cmd;
476  cmd.pipeline = compute_pipeline;
477 
478  CS::Info info{.count = kCount};
479  CS::Input0<kCount> input_0;
480  CS::Input1<kCount> input_1;
481  for (size_t i = 0; i < kCount; i++) {
482  input_0.elements[i] = Vector4(2.0 + i, 3.0 + i, 4.0 + i, 5.0 * i);
483  input_1.elements[i] = Vector4(6.0, 7.0, 8.0, 9.0);
484  }
485 
486  input_0.fixed_array[1] = IPoint32(2, 2);
487  input_1.fixed_array[0] = UintPoint32(3, 3);
488  input_0.some_int = 5;
489  input_1.some_struct = CS::SomeStruct{.vf = Point(3, 4), .i = 42};
490 
491  auto output_buffer = CreateHostVisibleDeviceBuffer<CS::Output<kCount>>(
492  context, "Output Buffer");
493 
494  CS::BindInfo(cmd, pass->GetTransientsBuffer().EmplaceUniform(info));
495  CS::BindInput0(cmd,
496  pass->GetTransientsBuffer().EmplaceStorageBuffer(input_0));
497  CS::BindInput1(cmd,
498  pass->GetTransientsBuffer().EmplaceStorageBuffer(input_1));
499  CS::BindOutput(cmd, output_buffer->AsBufferView());
500 
501  ASSERT_TRUE(pass->AddCommand(std::move(cmd)));
502  ASSERT_FALSE(pass->EncodeCommands());
503 }

References impeller::ComputeCommand::pipeline.

◆ TEST_P() [208/384]

impeller::testing::TEST_P ( DirectionalGaussianBlurFilterContentsTest  ,
CoverageWithEffectTransform   
)

Definition at line 39 of file directional_gaussian_blur_filter_contents_unittests.cc.

39  {
40  TextureDescriptor desc = {
41  .format = PixelFormat::kB8G8R8A8UNormInt,
42  .size = ISize(100, 100),
43  };
44  Scalar sigma_radius_1 = CalculateSigmaForBlurRadius(1.0);
45  auto contents = std::make_unique<DirectionalGaussianBlurFilterContents>();
46  contents->SetSigma(Sigma{sigma_radius_1});
47  contents->SetDirection({1.0, 0.0});
48  std::shared_ptr<Texture> texture =
49  GetContentContext()->GetContext()->GetResourceAllocator()->CreateTexture(
50  desc);
51  FilterInput::Vector inputs = {FilterInput::Make(texture)};
52  Entity entity;
53  entity.SetTransform(Matrix::MakeTranslation({100, 100, 0}));
54  std::optional<Rect> coverage = contents->GetFilterCoverage(
55  inputs, entity, /*effect_transform=*/Matrix::MakeScale({2.0, 2.0, 1.0}));
56  EXPECT_TRUE(coverage.has_value());
57  if (coverage.has_value()) {
58  EXPECT_NEAR(coverage->GetLeft(), 100 - 2,
59  0.5); // Higher tolerance for sigma scaling.
60  EXPECT_NEAR(coverage->GetTop(), 100, 0.01);
61  EXPECT_NEAR(coverage->GetRight(), 200 + 2,
62  0.5); // Higher tolerance for sigma scaling.
63  EXPECT_NEAR(coverage->GetBottom(), 200, 0.01);
64  }
65 }

References impeller::TextureDescriptor::format, impeller::kB8G8R8A8UNormInt, impeller::FilterInput::Make(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), and impeller::Entity::SetTransform().

◆ TEST_P() [209/384]

impeller::testing::TEST_P ( DirectionalGaussianBlurFilterContentsTest  ,
RenderCoverageMatchesGetCoverage   
)

Definition at line 91 of file directional_gaussian_blur_filter_contents_unittests.cc.

92  {
93  TextureDescriptor desc = {
94  .storage_mode = StorageMode::kDevicePrivate,
95  .format = PixelFormat::kB8G8R8A8UNormInt,
96  .size = ISize(100, 100),
97  };
98  std::shared_ptr<Texture> texture =
99  GetContentContext()->GetContext()->GetResourceAllocator()->CreateTexture(
100  desc);
101  Scalar sigma_radius_1 = CalculateSigmaForBlurRadius(1.0);
102  auto contents = std::make_unique<DirectionalGaussianBlurFilterContents>();
103  contents->SetSigma(Sigma{sigma_radius_1});
104  contents->SetDirection({1.0, 0.0});
105  contents->SetInputs({FilterInput::Make(texture)});
106  std::shared_ptr<ContentContext> renderer = GetContentContext();
107 
108  Entity entity;
109  std::optional<Entity> result =
110  contents->GetEntity(*renderer, entity, /*coverage_hint=*/{});
111  EXPECT_TRUE(result.has_value());
112  if (result.has_value()) {
113  EXPECT_EQ(result.value().GetBlendMode(), BlendMode::kSourceOver);
114  std::optional<Rect> result_coverage = result.value().GetCoverage();
115  std::optional<Rect> contents_coverage = contents->GetCoverage(entity);
116  EXPECT_TRUE(result_coverage.has_value());
117  EXPECT_TRUE(contents_coverage.has_value());
118  if (result_coverage.has_value() && contents_coverage.has_value()) {
119  EXPECT_TRUE(RectNear(result_coverage.value(), contents_coverage.value()));
120  // The precision on this blur is kind of off, thus the tolerance.
121  EXPECT_NEAR(result_coverage.value().GetLeft(), -1.f, 0.1f);
122  EXPECT_NEAR(result_coverage.value().GetTop(), 0.f, 0.001f);
123  EXPECT_NEAR(result_coverage.value().GetRight(), 101.f, 0.1f);
124  EXPECT_NEAR(result_coverage.value().GetBottom(), 100.f, 0.001f);
125  }
126  }
127 }

References impeller::kB8G8R8A8UNormInt, impeller::kDevicePrivate, impeller::kSourceOver, impeller::FilterInput::Make(), RectNear(), and impeller::TextureDescriptor::storage_mode.

◆ TEST_P() [210/384]

impeller::testing::TEST_P ( DirectionalGaussianBlurFilterContentsTest  ,
RenderNoCoverage   
)

Definition at line 78 of file directional_gaussian_blur_filter_contents_unittests.cc.

78  {
79  Scalar sigma_radius_1 = CalculateSigmaForBlurRadius(1.0);
80  auto contents = std::make_unique<DirectionalGaussianBlurFilterContents>();
81  contents->SetSigma(Sigma{sigma_radius_1});
82  contents->SetDirection({1.0, 0.0});
83  std::shared_ptr<ContentContext> renderer = GetContentContext();
84  Entity entity;
85  Rect coverage_hint = Rect::MakeLTRB(0, 0, 0, 0);
86  std::optional<Entity> result =
87  contents->GetEntity(*renderer, entity, coverage_hint);
88  ASSERT_FALSE(result.has_value());
89 }

References impeller::TRect< Scalar >::MakeLTRB().

◆ TEST_P() [211/384]

impeller::testing::TEST_P ( DirectionalGaussianBlurFilterContentsTest  ,
TextureContentsWithDestinationRect   
)

Definition at line 129 of file directional_gaussian_blur_filter_contents_unittests.cc.

130  {
131  TextureDescriptor desc = {
132  .storage_mode = StorageMode::kDevicePrivate,
133  .format = PixelFormat::kB8G8R8A8UNormInt,
134  .size = ISize(100, 100),
135  };
136 
137  std::shared_ptr<Texture> texture =
138  GetContentContext()->GetContext()->GetResourceAllocator()->CreateTexture(
139  desc);
140  auto texture_contents = std::make_shared<TextureContents>();
141  texture_contents->SetSourceRect(Rect::MakeSize(texture->GetSize()));
142  texture_contents->SetTexture(texture);
143  texture_contents->SetDestinationRect(Rect::MakeXYWH(
144  50, 40, texture->GetSize().width, texture->GetSize().height));
145 
146  Scalar sigma_radius_1 = CalculateSigmaForBlurRadius(1.0);
147  auto contents = std::make_unique<DirectionalGaussianBlurFilterContents>();
148  contents->SetSigma(Sigma{sigma_radius_1});
149  contents->SetDirection({1.0, 0.0});
150  contents->SetInputs({FilterInput::Make(texture_contents)});
151  std::shared_ptr<ContentContext> renderer = GetContentContext();
152 
153  Entity entity;
154  std::optional<Entity> result =
155  contents->GetEntity(*renderer, entity, /*coverage_hint=*/{});
156  EXPECT_TRUE(result.has_value());
157  if (result.has_value()) {
158  EXPECT_EQ(result.value().GetBlendMode(), BlendMode::kSourceOver);
159  std::optional<Rect> result_coverage = result.value().GetCoverage();
160  std::optional<Rect> contents_coverage = contents->GetCoverage(entity);
161  EXPECT_TRUE(result_coverage.has_value());
162  EXPECT_TRUE(contents_coverage.has_value());
163  if (result_coverage.has_value() && contents_coverage.has_value()) {
164  EXPECT_TRUE(RectNear(result_coverage.value(), contents_coverage.value()));
165  // The precision on this blur is kind of off, thus the tolerance.
166  EXPECT_NEAR(result_coverage.value().GetLeft(), 49.f, 0.1f);
167  EXPECT_NEAR(result_coverage.value().GetTop(), 40.f, 0.001f);
168  EXPECT_NEAR(result_coverage.value().GetRight(), 151.f, 0.1f);
169  EXPECT_NEAR(result_coverage.value().GetBottom(), 140.f, 0.001f);
170  }
171  }
172 }

References impeller::kB8G8R8A8UNormInt, impeller::kDevicePrivate, impeller::kSourceOver, impeller::FilterInput::Make(), impeller::TRect< Scalar >::MakeSize(), impeller::TRect< Scalar >::MakeXYWH(), RectNear(), and impeller::TextureDescriptor::storage_mode.

◆ TEST_P() [212/384]

impeller::testing::TEST_P ( DirectionalGaussianBlurFilterContentsTest  ,
TextureContentsWithDestinationRectScaled   
)

Definition at line 174 of file directional_gaussian_blur_filter_contents_unittests.cc.

175  {
176  TextureDescriptor desc = {
177  .storage_mode = StorageMode::kDevicePrivate,
178  .format = PixelFormat::kB8G8R8A8UNormInt,
179  .size = ISize(100, 100),
180  };
181 
182  std::shared_ptr<Texture> texture =
183  GetContentContext()->GetContext()->GetResourceAllocator()->CreateTexture(
184  desc);
185  auto texture_contents = std::make_shared<TextureContents>();
186  texture_contents->SetSourceRect(Rect::MakeSize(texture->GetSize()));
187  texture_contents->SetTexture(texture);
188  texture_contents->SetDestinationRect(Rect::MakeXYWH(
189  50, 40, texture->GetSize().width, texture->GetSize().height));
190 
191  Scalar sigma_radius_1 = CalculateSigmaForBlurRadius(1.0);
192  auto contents = std::make_unique<DirectionalGaussianBlurFilterContents>();
193  contents->SetSigma(Sigma{sigma_radius_1});
194  contents->SetDirection({1.0, 0.0});
195  contents->SetInputs({FilterInput::Make(texture_contents)});
196  std::shared_ptr<ContentContext> renderer = GetContentContext();
197 
198  Entity entity;
199  entity.SetTransform(Matrix::MakeScale({2.0, 2.0, 1.0}));
200  std::optional<Entity> result =
201  contents->GetEntity(*renderer, entity, /*coverage_hint=*/{});
202  EXPECT_TRUE(result.has_value());
203  if (result.has_value()) {
204  EXPECT_EQ(result.value().GetBlendMode(), BlendMode::kSourceOver);
205  std::optional<Rect> result_coverage = result.value().GetCoverage();
206  std::optional<Rect> contents_coverage = contents->GetCoverage(entity);
207  EXPECT_TRUE(result_coverage.has_value());
208  EXPECT_TRUE(contents_coverage.has_value());
209  if (result_coverage.has_value() && contents_coverage.has_value()) {
210  // The precision on this blur is kind of off, thus the tolerance.
211 
212  EXPECT_NEAR(result_coverage.value().GetLeft(), 98.f, 0.1f);
213  EXPECT_NEAR(result_coverage.value().GetTop(), 80.f, 0.001f);
214  EXPECT_NEAR(result_coverage.value().GetRight(), 302.f, 0.1f);
215  EXPECT_NEAR(result_coverage.value().GetBottom(), 280.f, 0.001f);
216 
217  EXPECT_NEAR(contents_coverage.value().GetLeft(), 98.f, 0.1f);
218  EXPECT_NEAR(contents_coverage.value().GetTop(), 80.f, 0.001f);
219  EXPECT_NEAR(contents_coverage.value().GetRight(), 302.f, 0.1f);
220  EXPECT_NEAR(contents_coverage.value().GetBottom(), 280.f, 0.001f);
221  }
222  }
223 }

References impeller::kB8G8R8A8UNormInt, impeller::kDevicePrivate, impeller::kSourceOver, impeller::FilterInput::Make(), impeller::Matrix::MakeScale(), impeller::TRect< Scalar >::MakeSize(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Entity::SetTransform(), and impeller::TextureDescriptor::storage_mode.

◆ TEST_P() [213/384]

impeller::testing::TEST_P ( DisplayListTest  ,
CanBlendDstOverAndDstCorrectly   
)

Definition at line 1264 of file dl_unittests.cc.

1264  {
1265  flutter::DisplayListBuilder builder;
1266 
1267  {
1268  builder.SaveLayer(nullptr, nullptr);
1269  builder.Translate(100, 100);
1270  flutter::DlPaint paint;
1271  paint.setColor(flutter::DlColor::kRed());
1272  builder.DrawRect(SkRect::MakeSize({200, 200}), paint);
1273  paint.setColor(flutter::DlColor::kBlue().withAlpha(127));
1274  paint.setBlendMode(flutter::DlBlendMode::kSrcOver);
1275  builder.DrawRect(SkRect::MakeSize({200, 200}), paint);
1276  builder.Restore();
1277  }
1278  {
1279  builder.SaveLayer(nullptr, nullptr);
1280  builder.Translate(300, 100);
1281  flutter::DlPaint paint;
1282  paint.setColor(flutter::DlColor::kBlue().withAlpha(127));
1283  builder.DrawRect(SkRect::MakeSize({200, 200}), paint);
1284  paint.setColor(flutter::DlColor::kRed());
1285  paint.setBlendMode(flutter::DlBlendMode::kDstOver);
1286  builder.DrawRect(SkRect::MakeSize({200, 200}), paint);
1287  builder.Restore();
1288  }
1289  {
1290  builder.SaveLayer(nullptr, nullptr);
1291  builder.Translate(100, 300);
1292  flutter::DlPaint paint;
1293  paint.setColor(flutter::DlColor::kRed());
1294  builder.DrawRect(SkRect::MakeSize({200, 200}), paint);
1295  paint.setColor(flutter::DlColor::kBlue().withAlpha(127));
1296  paint.setBlendMode(flutter::DlBlendMode::kSrc);
1297  builder.DrawRect(SkRect::MakeSize({200, 200}), paint);
1298  builder.Restore();
1299  }
1300  {
1301  builder.SaveLayer(nullptr, nullptr);
1302  builder.Translate(300, 300);
1303  flutter::DlPaint paint;
1304  paint.setColor(flutter::DlColor::kBlue().withAlpha(127));
1305  builder.DrawRect(SkRect::MakeSize({200, 200}), paint);
1306  paint.setColor(flutter::DlColor::kRed());
1307  paint.setBlendMode(flutter::DlBlendMode::kDst);
1308  builder.DrawRect(SkRect::MakeSize({200, 200}), paint);
1309  builder.Restore();
1310  }
1311 
1312  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1313 }

◆ TEST_P() [214/384]

impeller::testing::TEST_P ( DisplayListTest  ,
CanClampTheResultingColorOfColorMatrixFilter   
)

Definition at line 628 of file dl_unittests.cc.

628  {
629  auto texture = CreateTextureForFixture("boston.jpg");
630  const float inner_color_matrix[20] = {
631  1, 0, 0, 0, 0, //
632  0, 1, 0, 0, 0, //
633  0, 0, 1, 0, 0, //
634  0, 0, 0, 2, 0, //
635  };
636  const float outer_color_matrix[20] = {
637  1, 0, 0, 0, 0, //
638  0, 1, 0, 0, 0, //
639  0, 0, 1, 0, 0, //
640  0, 0, 0, 0.5, 0, //
641  };
642  auto inner_color_filter =
643  std::make_shared<flutter::DlMatrixColorFilter>(inner_color_matrix);
644  auto outer_color_filter =
645  std::make_shared<flutter::DlMatrixColorFilter>(outer_color_matrix);
646  auto inner =
647  std::make_shared<flutter::DlColorFilterImageFilter>(inner_color_filter);
648  auto outer =
649  std::make_shared<flutter::DlColorFilterImageFilter>(outer_color_filter);
650  auto compose = std::make_shared<flutter::DlComposeImageFilter>(outer, inner);
651 
652  flutter::DisplayListBuilder builder;
653  flutter::DlPaint paint;
654  paint.setImageFilter(compose.get());
655  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
656  flutter::DlImageSampling::kNearestNeighbor, &paint);
657  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
658 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [215/384]

impeller::testing::TEST_P ( DisplayListTest  ,
CanConvertTriangleFanToTriangles   
)

Definition at line 975 of file dl_unittests.cc.

975  {
976  constexpr Scalar hexagon_radius = 125;
977  auto hex_start = Point(200.0, -hexagon_radius + 200.0);
978  auto center_to_flat = 1.73 / 2 * hexagon_radius;
979 
980  // clang-format off
981  std::vector<SkPoint> vertices = {
982  SkPoint::Make(hex_start.x, hex_start.y),
983  SkPoint::Make(hex_start.x + center_to_flat, hex_start.y + 0.5 * hexagon_radius),
984  SkPoint::Make(hex_start.x + center_to_flat, hex_start.y + 1.5 * hexagon_radius),
985  SkPoint::Make(hex_start.x + center_to_flat, hex_start.y + 1.5 * hexagon_radius),
986  SkPoint::Make(hex_start.x, hex_start.y + 2 * hexagon_radius),
987  SkPoint::Make(hex_start.x, hex_start.y + 2 * hexagon_radius),
988  SkPoint::Make(hex_start.x - center_to_flat, hex_start.y + 1.5 * hexagon_radius),
989  SkPoint::Make(hex_start.x - center_to_flat, hex_start.y + 1.5 * hexagon_radius),
990  SkPoint::Make(hex_start.x - center_to_flat, hex_start.y + 0.5 * hexagon_radius)
991  };
992  // clang-format on
993  auto paint = flutter::DlPaint(flutter::DlColor::kDarkGrey());
994  auto dl_vertices = flutter::DlVertices::Make(
995  flutter::DlVertexMode::kTriangleFan, vertices.size(), vertices.data(),
996  nullptr, nullptr);
997  flutter::DisplayListBuilder builder;
998  builder.DrawVertices(dl_vertices, flutter::DlBlendMode::kSrcOver, paint);
999  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1000 }

◆ TEST_P() [216/384]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawAnOpenPath   
)

Definition at line 418 of file dl_unittests.cc.

418  {
419  flutter::DisplayListBuilder builder;
420  flutter::DlPaint paint;
421 
422  paint.setColor(flutter::DlColor::kRed());
423  paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
424  paint.setStrokeWidth(10);
425 
426  builder.Translate(300, 300);
427 
428  // Move to (50, 50) and draw lines from:
429  // 1. (50, height)
430  // 2. (width, height)
431  // 3. (width, 50)
432  SkPath path;
433  path.moveTo(50, 50);
434  path.lineTo(50, 100);
435  path.lineTo(100, 100);
436  path.lineTo(100, 50);
437  builder.DrawPath(path, paint);
438 
439  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
440 }

◆ TEST_P() [217/384]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawArc   
)

Definition at line 165 of file dl_unittests.cc.

165  {
166  auto callback = [&]() {
167  static float start_angle = 45;
168  static float sweep_angle = 270;
169  static float stroke_width = 10;
170  static bool use_center = true;
171 
172  static int selected_cap = 0;
173  const char* cap_names[] = {"Butt", "Round", "Square"};
174  flutter::DlStrokeCap cap;
175 
176  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
177  ImGui::SliderFloat("Start angle", &start_angle, -360, 360);
178  ImGui::SliderFloat("Sweep angle", &sweep_angle, -360, 360);
179  ImGui::SliderFloat("Stroke width", &stroke_width, 0, 300);
180  ImGui::Combo("Cap", &selected_cap, cap_names,
181  sizeof(cap_names) / sizeof(char*));
182  ImGui::Checkbox("Use center", &use_center);
183  ImGui::End();
184 
185  switch (selected_cap) {
186  case 0:
187  cap = flutter::DlStrokeCap::kButt;
188  break;
189  case 1:
190  cap = flutter::DlStrokeCap::kRound;
191  break;
192  case 2:
193  cap = flutter::DlStrokeCap::kSquare;
194  break;
195  default:
196  cap = flutter::DlStrokeCap::kButt;
197  break;
198  }
199 
200  auto [p1, p2] = IMPELLER_PLAYGROUND_LINE(
201  Point(200, 200), Point(400, 400), 20, Color::White(), Color::White());
202 
203  flutter::DisplayListBuilder builder;
204  flutter::DlPaint paint;
205 
206  Vector2 scale = GetContentScale();
207  builder.Scale(scale.x, scale.y);
208  paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
209  paint.setStrokeCap(cap);
210  paint.setStrokeJoin(flutter::DlStrokeJoin::kMiter);
211  paint.setStrokeMiter(10);
212  auto rect = SkRect::MakeLTRB(p1.x, p1.y, p2.x, p2.y);
213  paint.setColor(flutter::DlColor::kGreen());
214  paint.setStrokeWidth(2);
215  builder.DrawRect(rect, paint);
216  paint.setColor(flutter::DlColor::kRed());
217  paint.setStrokeWidth(stroke_width);
218  builder.DrawArc(rect, start_angle, sweep_angle, use_center, paint);
219 
220  return builder.Build();
221  };
222  ASSERT_TRUE(OpenPlaygroundHere(callback));
223 }

References IMPELLER_PLAYGROUND_LINE, impeller::Color::White(), impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ TEST_P() [218/384]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawBackdropFilter   
)

Definition at line 660 of file dl_unittests.cc.

660  {
661  auto texture = CreateTextureForFixture("embarcadero.jpg");
662 
663  auto callback = [&]() {
664  static float sigma[] = {10, 10};
665  static float ctm_scale = 1;
666  static bool use_bounds = true;
667  static bool draw_circle = true;
668  static bool add_clip = true;
669 
670  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
671  ImGui::SliderFloat2("Sigma", sigma, 0, 100);
672  ImGui::SliderFloat("Scale", &ctm_scale, 0, 10);
673  ImGui::NewLine();
674  ImGui::TextWrapped(
675  "If everything is working correctly, none of the options below should "
676  "impact the filter's appearance.");
677  ImGui::Checkbox("Use SaveLayer bounds", &use_bounds);
678  ImGui::Checkbox("Draw child element", &draw_circle);
679  ImGui::Checkbox("Add pre-clip", &add_clip);
680  ImGui::End();
681 
682  flutter::DisplayListBuilder builder;
683 
684  Vector2 scale = ctm_scale * GetContentScale();
685  builder.Scale(scale.x, scale.y);
686 
687  auto filter = flutter::DlBlurImageFilter(sigma[0], sigma[1],
688  flutter::DlTileMode::kClamp);
689 
690  std::optional<SkRect> bounds;
691  if (use_bounds) {
692  auto [p1, p2] = IMPELLER_PLAYGROUND_LINE(
693  Point(350, 150), Point(800, 600), 20, Color::White(), Color::White());
694  bounds = SkRect::MakeLTRB(p1.x, p1.y, p2.x, p2.y);
695  }
696 
697  // Insert a clip to test that the backdrop filter handles stencil depths > 0
698  // correctly.
699  if (add_clip) {
700  builder.ClipRect(SkRect::MakeLTRB(0, 0, 99999, 99999),
701  flutter::DlCanvas::ClipOp::kIntersect, true);
702  }
703 
704  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(200, 200),
705  flutter::DlImageSampling::kNearestNeighbor, nullptr);
706  builder.SaveLayer(bounds.has_value() ? &bounds.value() : nullptr, nullptr,
707  &filter);
708 
709  if (draw_circle) {
710  auto circle_center =
711  IMPELLER_PLAYGROUND_POINT(Point(500, 400), 20, Color::Red());
712 
713  flutter::DlPaint paint;
714  paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
715  paint.setStrokeCap(flutter::DlStrokeCap::kButt);
716  paint.setStrokeJoin(flutter::DlStrokeJoin::kBevel);
717  paint.setStrokeWidth(10);
718  paint.setColor(flutter::DlColor::kRed().withAlpha(100));
719  builder.DrawCircle({circle_center.x, circle_center.y}, 100, paint);
720  }
721 
722  return builder.Build();
723  };
724 
725  ASSERT_TRUE(OpenPlaygroundHere(callback));
726 }

References IMPELLER_PLAYGROUND_LINE, IMPELLER_PLAYGROUND_POINT, impeller::DlImageImpeller::Make(), impeller::Color::Red(), impeller::Color::White(), impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ TEST_P() [219/384]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawCapsAndJoins   
)

Definition at line 119 of file dl_unittests.cc.

119  {
120  flutter::DisplayListBuilder builder;
121  flutter::DlPaint paint;
122 
123  paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
124  paint.setStrokeWidth(30);
125  paint.setColor(flutter::DlColor::kRed());
126 
127  auto path =
128  SkPathBuilder{}.moveTo(-50, 0).lineTo(0, -50).lineTo(50, 0).snapshot();
129 
130  builder.Translate(100, 100);
131  {
132  paint.setStrokeCap(flutter::DlStrokeCap::kButt);
133  paint.setStrokeJoin(flutter::DlStrokeJoin::kMiter);
134  paint.setStrokeMiter(4);
135  builder.DrawPath(path, paint);
136  }
137 
138  {
139  builder.Save();
140  builder.Translate(0, 100);
141  // The joint in the path is 45 degrees. A miter length of 1 convert to a
142  // bevel in this case.
143  paint.setStrokeMiter(1);
144  builder.DrawPath(path, paint);
145  builder.Restore();
146  }
147 
148  builder.Translate(150, 0);
149  {
150  paint.setStrokeCap(flutter::DlStrokeCap::kSquare);
151  paint.setStrokeJoin(flutter::DlStrokeJoin::kBevel);
152  builder.DrawPath(path, paint);
153  }
154 
155  builder.Translate(150, 0);
156  {
157  paint.setStrokeCap(flutter::DlStrokeCap::kRound);
158  paint.setStrokeJoin(flutter::DlStrokeJoin::kRound);
159  builder.DrawPath(path, paint);
160  }
161 
162  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
163 }

◆ TEST_P() [220/384]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawCorrectlyWithColorFilterAndImageFilter   
)

Definition at line 1315 of file dl_unittests.cc.

1315  {
1316  flutter::DisplayListBuilder builder;
1317  const float green_color_matrix[20] = {
1318  0, 0, 0, 0, 0, //
1319  0, 0, 0, 0, 1, //
1320  0, 0, 0, 0, 0, //
1321  0, 0, 0, 1, 0, //
1322  };
1323  const float blue_color_matrix[20] = {
1324  0, 0, 0, 0, 0, //
1325  0, 0, 0, 0, 0, //
1326  0, 0, 0, 0, 1, //
1327  0, 0, 0, 1, 0, //
1328  };
1329  auto green_color_filter =
1330  std::make_shared<flutter::DlMatrixColorFilter>(green_color_matrix);
1331  auto blue_color_filter =
1332  std::make_shared<flutter::DlMatrixColorFilter>(blue_color_matrix);
1333  auto blue_image_filter =
1334  std::make_shared<flutter::DlColorFilterImageFilter>(blue_color_filter);
1335 
1336  flutter::DlPaint paint;
1337  paint.setColor(flutter::DlColor::kRed());
1338  paint.setColorFilter(green_color_filter);
1339  paint.setImageFilter(blue_image_filter);
1340  builder.DrawRect(SkRect::MakeLTRB(100, 100, 500, 500), paint);
1341  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1342 }

◆ TEST_P() [221/384]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawImage   
)

Definition at line 111 of file dl_unittests.cc.

111  {
112  auto texture = CreateTextureForFixture("embarcadero.jpg");
113  flutter::DisplayListBuilder builder;
114  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
115  flutter::DlImageSampling::kNearestNeighbor, nullptr);
116  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
117 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [222/384]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawNinePatchImage   
)

Definition at line 728 of file dl_unittests.cc.

728  {
729  // Image is drawn with corners to scale and center pieces stretched to fit.
730  auto texture = CreateTextureForFixture("embarcadero.jpg");
731  flutter::DisplayListBuilder builder;
732  auto size = texture->GetSize();
733  builder.DrawImageNine(
734  DlImageImpeller::Make(texture),
735  SkIRect::MakeLTRB(size.width / 4, size.height / 4, size.width * 3 / 4,
736  size.height * 3 / 4),
737  SkRect::MakeLTRB(0, 0, size.width * 2, size.height * 2),
738  flutter::DlFilterMode::kNearest, nullptr);
739  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
740 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [223/384]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawNinePatchImageCenterBiggerThanDest   
)

Definition at line 774 of file dl_unittests.cc.

774  {
775  // Edge case, the width and height of the corners does not leave any
776  // room for the center slices. Only the corners are displayed.
777  auto texture = CreateTextureForFixture("embarcadero.jpg");
778  flutter::DisplayListBuilder builder;
779  auto size = texture->GetSize();
780  builder.DrawImageNine(
781  DlImageImpeller::Make(texture),
782  SkIRect::MakeLTRB(size.width / 4, size.height / 4, size.width * 3 / 4,
783  size.height * 3 / 4),
784  SkRect::MakeLTRB(0, 0, size.width / 2, size.height / 2),
785  flutter::DlFilterMode::kNearest, nullptr);
786  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
787 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [224/384]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawNinePatchImageCenterHeightBiggerThanDest   
)

Definition at line 758 of file dl_unittests.cc.

758  {
759  // Edge case, the height of the corners does not leave any room for the
760  // center slice. The center (across the horizontal axis) is folded out of the
761  // resulting image.
762  auto texture = CreateTextureForFixture("embarcadero.jpg");
763  flutter::DisplayListBuilder builder;
764  auto size = texture->GetSize();
765  builder.DrawImageNine(
766  DlImageImpeller::Make(texture),
767  SkIRect::MakeLTRB(size.width / 4, size.height / 4, size.width * 3 / 4,
768  size.height * 3 / 4),
769  SkRect::MakeLTRB(0, 0, size.width, size.height / 2),
770  flutter::DlFilterMode::kNearest, nullptr);
771  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
772 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [225/384]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawNinePatchImageCenterWidthBiggerThanDest   
)

Definition at line 742 of file dl_unittests.cc.

742  {
743  // Edge case, the width of the corners does not leave any room for the
744  // center slice. The center (across the vertical axis) is folded out of the
745  // resulting image.
746  auto texture = CreateTextureForFixture("embarcadero.jpg");
747  flutter::DisplayListBuilder builder;
748  auto size = texture->GetSize();
749  builder.DrawImageNine(
750  DlImageImpeller::Make(texture),
751  SkIRect::MakeLTRB(size.width / 4, size.height / 4, size.width * 3 / 4,
752  size.height * 3 / 4),
753  SkRect::MakeLTRB(0, 0, size.width / 2, size.height),
754  flutter::DlFilterMode::kNearest, nullptr);
755  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
756 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [226/384]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawNinePatchImageCornersScaledDown   
)

Definition at line 789 of file dl_unittests.cc.

789  {
790  // Edge case, there is not enough room for the corners to be drawn
791  // without scaling them down.
792  auto texture = CreateTextureForFixture("embarcadero.jpg");
793  flutter::DisplayListBuilder builder;
794  auto size = texture->GetSize();
795  builder.DrawImageNine(
796  DlImageImpeller::Make(texture),
797  SkIRect::MakeLTRB(size.width / 4, size.height / 4, size.width * 3 / 4,
798  size.height * 3 / 4),
799  SkRect::MakeLTRB(0, 0, size.width / 4, size.height / 4),
800  flutter::DlFilterMode::kNearest, nullptr);
801  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
802 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [227/384]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawPaintWithColorSource   
)

Definition at line 1212 of file dl_unittests.cc.

1212  {
1213  const flutter::DlColor colors[2] = {
1214  flutter::DlColor(0xFFF44336),
1215  flutter::DlColor(0xFF2196F3),
1216  };
1217  const float stops[2] = {0.0, 1.0};
1218  flutter::DlPaint paint;
1219  flutter::DisplayListBuilder builder;
1220  auto clip_bounds = SkRect::MakeWH(300.0, 300.0);
1221  builder.Save();
1222  builder.Translate(100, 100);
1223  builder.ClipRect(clip_bounds, flutter::DlCanvas::ClipOp::kIntersect, false);
1224  auto linear =
1225  flutter::DlColorSource::MakeLinear({0.0, 0.0}, {100.0, 100.0}, 2, colors,
1226  stops, flutter::DlTileMode::kRepeat);
1227  paint.setColorSource(linear);
1228  builder.DrawPaint(paint);
1229  builder.Restore();
1230 
1231  builder.Save();
1232  builder.Translate(500, 100);
1233  builder.ClipRect(clip_bounds, flutter::DlCanvas::ClipOp::kIntersect, false);
1234  auto radial = flutter::DlColorSource::MakeRadial(
1235  {100.0, 100.0}, 100.0, 2, colors, stops, flutter::DlTileMode::kRepeat);
1236  paint.setColorSource(radial);
1237  builder.DrawPaint(paint);
1238  builder.Restore();
1239 
1240  builder.Save();
1241  builder.Translate(100, 500);
1242  builder.ClipRect(clip_bounds, flutter::DlCanvas::ClipOp::kIntersect, false);
1243  auto sweep =
1244  flutter::DlColorSource::MakeSweep({100.0, 100.0}, 180.0, 270.0, 2, colors,
1245  stops, flutter::DlTileMode::kRepeat);
1246  paint.setColorSource(sweep);
1247  builder.DrawPaint(paint);
1248  builder.Restore();
1249 
1250  builder.Save();
1251  builder.Translate(500, 500);
1252  builder.ClipRect(clip_bounds, flutter::DlCanvas::ClipOp::kIntersect, false);
1253  auto texture = CreateTextureForFixture("table_mountain_nx.png");
1254  auto image = std::make_shared<flutter::DlImageColorSource>(
1255  DlImageImpeller::Make(texture), flutter::DlTileMode::kRepeat,
1256  flutter::DlTileMode::kRepeat);
1257  paint.setColorSource(image);
1258  builder.DrawPaint(paint);
1259  builder.Restore();
1260 
1261  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1262 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [228/384]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawPoints   
)

Definition at line 804 of file dl_unittests.cc.

804  {
805  flutter::DisplayListBuilder builder;
806  SkPoint points[7] = {
807  {0, 0}, //
808  {100, 100}, //
809  {100, 0}, //
810  {0, 100}, //
811  {0, 0}, //
812  {48, 48}, //
813  {52, 52}, //
814  };
815  std::vector<flutter::DlStrokeCap> caps = {
816  flutter::DlStrokeCap::kButt,
817  flutter::DlStrokeCap::kRound,
818  flutter::DlStrokeCap::kSquare,
819  };
820  flutter::DlPaint paint =
821  flutter::DlPaint() //
822  .setColor(flutter::DlColor::kYellow().withAlpha(127)) //
823  .setStrokeWidth(20);
824  builder.Translate(50, 50);
825  for (auto cap : caps) {
826  paint.setStrokeCap(cap);
827  builder.Save();
828  builder.DrawPoints(flutter::DlCanvas::PointMode::kPoints, 7, points, paint);
829  builder.Translate(150, 0);
830  builder.DrawPoints(flutter::DlCanvas::PointMode::kLines, 5, points, paint);
831  builder.Translate(150, 0);
832  builder.DrawPoints(flutter::DlCanvas::PointMode::kPolygon, 5, points,
833  paint);
834  builder.Restore();
835  builder.Translate(0, 150);
836  }
837  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
838 }

◆ TEST_P() [229/384]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawRect   
)

Definition at line 62 of file dl_unittests.cc.

62  {
63  flutter::DisplayListBuilder builder;
64  builder.DrawRect(SkRect::MakeXYWH(10, 10, 100, 100),
65  flutter::DlPaint(flutter::DlColor::kBlue()));
66  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
67 }

◆ TEST_P() [230/384]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawRectWithLinearToSrgbColorFilter   
)

Definition at line 1196 of file dl_unittests.cc.

1196  {
1197  flutter::DlPaint paint;
1198  paint.setColor(flutter::DlColor(0xFF2196F3).withAlpha(128));
1199  flutter::DisplayListBuilder builder;
1200  paint.setColorFilter(
1201  flutter::DlLinearToSrgbGammaColorFilter::kInstance.get());
1202  builder.DrawRect(SkRect::MakeXYWH(0, 0, 200, 200), paint);
1203  builder.Translate(0, 200);
1204 
1205  paint.setColorFilter(
1206  flutter::DlSrgbToLinearGammaColorFilter::kInstance.get());
1207  builder.DrawRect(SkRect::MakeXYWH(0, 0, 200, 200), paint);
1208 
1209  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1210 }

◆ TEST_P() [231/384]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawShadow   
)

Definition at line 863 of file dl_unittests.cc.

863  {
864  flutter::DisplayListBuilder builder;
865  flutter::DlPaint paint;
866 
867  auto content_scale = GetContentScale() * 0.8;
868  builder.Scale(content_scale.x, content_scale.y);
869 
870  constexpr size_t star_spikes = 5;
871  constexpr SkScalar half_spike_rotation = kPi / star_spikes;
872  constexpr SkScalar radius = 40;
873  constexpr SkScalar spike_size = 10;
874  constexpr SkScalar outer_radius = radius + spike_size;
875  constexpr SkScalar inner_radius = radius - spike_size;
876  std::array<SkPoint, star_spikes * 2> star;
877  for (size_t i = 0; i < star_spikes; i++) {
878  const SkScalar rotation = half_spike_rotation * i * 2;
879  star[i * 2] = SkPoint::Make(50 + std::sin(rotation) * outer_radius,
880  50 - std::cos(rotation) * outer_radius);
881  star[i * 2 + 1] = SkPoint::Make(
882  50 + std::sin(rotation + half_spike_rotation) * inner_radius,
883  50 - std::cos(rotation + half_spike_rotation) * inner_radius);
884  }
885 
886  std::array<SkPath, 4> paths = {
887  SkPath{}.addRect(SkRect::MakeXYWH(0, 0, 200, 100)),
888  SkPath{}.addRRect(
889  SkRRect::MakeRectXY(SkRect::MakeXYWH(20, 0, 200, 100), 30, 30)),
890  SkPath{}.addCircle(100, 50, 50),
891  SkPath{}.addPoly(star.data(), star.size(), true),
892  };
893  paint.setColor(flutter::DlColor::kWhite());
894  builder.DrawPaint(paint);
895  paint.setColor(flutter::DlColor::kCyan());
896  builder.Translate(100, 50);
897  for (size_t x = 0; x < paths.size(); x++) {
898  builder.Save();
899  for (size_t y = 0; y < 6; y++) {
900  builder.DrawShadow(paths[x], flutter::DlColor::kBlack(), 3 + y * 8, false,
901  1);
902  builder.DrawPath(paths[x], paint);
903  builder.Translate(0, 150);
904  }
905  builder.Restore();
906  builder.Translate(250, 0);
907  }
908 
909  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
910 }

References impeller::kPi.

◆ TEST_P() [232/384]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawStrokedText   
)

Definition at line 478 of file dl_unittests.cc.

478  {
479  flutter::DisplayListBuilder builder;
480  flutter::DlPaint paint;
481 
482  paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
483  paint.setColor(flutter::DlColor::kRed());
484  builder.DrawTextBlob(
485  SkTextBlob::MakeFromString("stoked about stroked text", CreateTestFont()),
486  250, 250, paint);
487 
488  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
489 }

◆ TEST_P() [233/384]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawTextBlob   
)

Definition at line 69 of file dl_unittests.cc.

69  {
70  flutter::DisplayListBuilder builder;
71  builder.DrawTextBlob(SkTextBlob::MakeFromString("Hello", CreateTestFont()),
72  100, 100, flutter::DlPaint(flutter::DlColor::kBlue()));
73  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
74 }

◆ TEST_P() [234/384]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawTextBlobWithGradient   
)

Definition at line 76 of file dl_unittests.cc.

76  {
77  flutter::DisplayListBuilder builder;
78 
79  std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
80  flutter::DlColor::kRed()};
81  const float stops[2] = {0.0, 1.0};
82 
83  auto linear = flutter::DlColorSource::MakeLinear({0.0, 0.0}, {300.0, 300.0},
84  2, colors.data(), stops,
85  flutter::DlTileMode::kClamp);
86  flutter::DlPaint paint;
87  paint.setColorSource(linear);
88 
89  builder.DrawTextBlob(
90  SkTextBlob::MakeFromString("Hello World", CreateTestFont()), 100, 100,
91  paint);
92  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
93 }

◆ TEST_P() [235/384]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawTextWithSaveLayer   
)

Definition at line 95 of file dl_unittests.cc.

95  {
96  flutter::DisplayListBuilder builder;
97  builder.DrawTextBlob(SkTextBlob::MakeFromString("Hello", CreateTestFont()),
98  100, 100, flutter::DlPaint(flutter::DlColor::kRed()));
99 
100  flutter::DlPaint save_paint;
101  float alpha = 0.5;
102  save_paint.setAlpha(static_cast<uint8_t>(255 * alpha));
103  builder.SaveLayer(nullptr, &save_paint);
104  builder.DrawTextBlob(SkTextBlob::MakeFromString("Hello with half alpha",
105  CreateTestFontOfSize(100)),
106  100, 300, flutter::DlPaint(flutter::DlColor::kRed()));
107  builder.Restore();
108  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
109 }

◆ TEST_P() [236/384]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithBlendColorFilter   
)

Definition at line 530 of file dl_unittests.cc.

530  {
531  auto texture = CreateTextureForFixture("embarcadero.jpg");
532  flutter::DisplayListBuilder builder;
533  flutter::DlPaint paint;
534 
535  // Pipeline blended image.
536  {
537  auto filter = flutter::DlBlendColorFilter(flutter::DlColor::kYellow(),
538  flutter::DlBlendMode::kModulate);
539  paint.setColorFilter(&filter);
540  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
541  flutter::DlImageSampling::kNearestNeighbor, &paint);
542  }
543 
544  // Advanced blended image.
545  {
546  auto filter = flutter::DlBlendColorFilter(flutter::DlColor::kRed(),
547  flutter::DlBlendMode::kScreen);
548  paint.setColorFilter(&filter);
549  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(250, 250),
550  flutter::DlImageSampling::kNearestNeighbor, &paint);
551  }
552 
553  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
554 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [237/384]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithColorFilterImageFilter   
)

Definition at line 556 of file dl_unittests.cc.

556  {
557  const float invert_color_matrix[20] = {
558  -1, 0, 0, 0, 1, //
559  0, -1, 0, 0, 1, //
560  0, 0, -1, 0, 1, //
561  0, 0, 0, 1, 0, //
562  };
563  auto texture = CreateTextureForFixture("boston.jpg");
564  flutter::DisplayListBuilder builder;
565  flutter::DlPaint paint;
566 
567  auto color_filter =
568  std::make_shared<flutter::DlMatrixColorFilter>(invert_color_matrix);
569  auto image_filter =
570  std::make_shared<flutter::DlColorFilterImageFilter>(color_filter);
571 
572  paint.setImageFilter(image_filter.get());
573  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
574  flutter::DlImageSampling::kNearestNeighbor, &paint);
575 
576  builder.Translate(0, 700);
577  paint.setColorFilter(color_filter.get());
578  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
579  flutter::DlImageSampling::kNearestNeighbor, &paint);
580  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
581 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [238/384]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithComposeImageFilter   
)

Definition at line 608 of file dl_unittests.cc.

608  {
609  auto texture = CreateTextureForFixture("boston.jpg");
610  flutter::DisplayListBuilder builder;
611  flutter::DlPaint paint;
612 
613  auto dilate = std::make_shared<flutter::DlDilateImageFilter>(10.0, 10.0);
614  auto erode = std::make_shared<flutter::DlErodeImageFilter>(10.0, 10.0);
615  auto open = std::make_shared<flutter::DlComposeImageFilter>(dilate, erode);
616  auto close = std::make_shared<flutter::DlComposeImageFilter>(erode, dilate);
617 
618  paint.setImageFilter(open.get());
619  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
620  flutter::DlImageSampling::kNearestNeighbor, &paint);
621  builder.Translate(0, 700);
622  paint.setImageFilter(close.get());
623  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
624  flutter::DlImageSampling::kNearestNeighbor, &paint);
625  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
626 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [239/384]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithImageBlurFilter   
)

Definition at line 583 of file dl_unittests.cc.

583  {
584  auto texture = CreateTextureForFixture("embarcadero.jpg");
585 
586  auto callback = [&]() {
587  static float sigma[] = {10, 10};
588 
589  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
590  ImGui::SliderFloat2("Sigma", sigma, 0, 100);
591  ImGui::End();
592 
593  flutter::DisplayListBuilder builder;
594  flutter::DlPaint paint;
595 
596  auto filter = flutter::DlBlurImageFilter(sigma[0], sigma[1],
597  flutter::DlTileMode::kClamp);
598  paint.setImageFilter(&filter);
599  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(200, 200),
600  flutter::DlImageSampling::kNearestNeighbor, &paint);
601 
602  return builder.Build();
603  };
604 
605  ASSERT_TRUE(OpenPlaygroundHere(callback));
606 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [240/384]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithMaskBlur   
)

Definition at line 442 of file dl_unittests.cc.

442  {
443  auto texture = CreateTextureForFixture("embarcadero.jpg");
444  flutter::DisplayListBuilder builder;
445  flutter::DlPaint paint;
446 
447  // Mask blurred image.
448  {
449  auto filter =
450  flutter::DlBlurMaskFilter(flutter::DlBlurStyle::kNormal, 10.0f);
451  paint.setMaskFilter(&filter);
452  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
453  flutter::DlImageSampling::kNearestNeighbor, &paint);
454  }
455 
456  // Mask blurred filled path.
457  {
458  paint.setColor(flutter::DlColor::kYellow());
459  auto filter =
460  flutter::DlBlurMaskFilter(flutter::DlBlurStyle::kOuter, 10.0f);
461  paint.setMaskFilter(&filter);
462  builder.DrawArc(SkRect::MakeXYWH(410, 110, 100, 100), 45, 270, true, paint);
463  }
464 
465  // Mask blurred text.
466  {
467  auto filter =
468  flutter::DlBlurMaskFilter(flutter::DlBlurStyle::kSolid, 10.0f);
469  paint.setMaskFilter(&filter);
470  builder.DrawTextBlob(
471  SkTextBlob::MakeFromString("Testing", CreateTestFont()), 220, 170,
472  paint);
473  }
474 
475  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
476 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [241/384]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithMatrixFilter   
)

Definition at line 1036 of file dl_unittests.cc.

1036  {
1037  auto boston = CreateTextureForFixture("boston.jpg");
1038 
1039  auto callback = [&]() {
1040  static int selected_matrix_type = 0;
1041  const char* matrix_type_names[] = {"Matrix", "Local Matrix"};
1042 
1043  static float ctm_translation[2] = {200, 200};
1044  static float ctm_scale[2] = {0.65, 0.65};
1045  static float ctm_skew[2] = {0, 0};
1046 
1047  static bool enable = true;
1048  static float translation[2] = {100, 100};
1049  static float scale[2] = {0.8, 0.8};
1050  static float skew[2] = {0.2, 0.2};
1051 
1052  static bool enable_savelayer = true;
1053 
1054  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1055  {
1056  ImGui::Combo("Filter type", &selected_matrix_type, matrix_type_names,
1057  sizeof(matrix_type_names) / sizeof(char*));
1058 
1059  ImGui::TextWrapped("Current Transform");
1060  ImGui::SliderFloat2("CTM Translation", ctm_translation, 0, 1000);
1061  ImGui::SliderFloat2("CTM Scale", ctm_scale, 0, 3);
1062  ImGui::SliderFloat2("CTM Skew", ctm_skew, -3, 3);
1063 
1064  ImGui::TextWrapped(
1065  "MatrixFilter and LocalMatrixFilter modify the CTM in the same way. "
1066  "The only difference is that MatrixFilter doesn't affect the effect "
1067  "transform, whereas LocalMatrixFilter does.");
1068  // Note: See this behavior in:
1069  // https://fiddle.skia.org/c/6cbb551ab36d06f163db8693972be954
1070  ImGui::Checkbox("Enable", &enable);
1071  ImGui::SliderFloat2("Filter Translation", translation, 0, 1000);
1072  ImGui::SliderFloat2("Filter Scale", scale, 0, 3);
1073  ImGui::SliderFloat2("Filter Skew", skew, -3, 3);
1074 
1075  ImGui::TextWrapped(
1076  "Rendering the filtered image within a layer can expose bounds "
1077  "issues. If the rendered image gets cut off when this setting is "
1078  "enabled, there's a coverage bug in the filter.");
1079  ImGui::Checkbox("Render in layer", &enable_savelayer);
1080  }
1081  ImGui::End();
1082 
1083  flutter::DisplayListBuilder builder;
1084  flutter::DlPaint paint;
1085 
1086  if (enable_savelayer) {
1087  builder.SaveLayer(nullptr, nullptr);
1088  }
1089  {
1090  auto content_scale = GetContentScale();
1091  builder.Scale(content_scale.x, content_scale.y);
1092 
1093  // Set the current transform
1094  auto ctm_matrix =
1095  SkMatrix::MakeAll(ctm_scale[0], ctm_skew[0], ctm_translation[0], //
1096  ctm_skew[1], ctm_scale[1], ctm_translation[1], //
1097  0, 0, 1);
1098  builder.Transform(ctm_matrix);
1099 
1100  // Set the matrix filter
1101  auto filter_matrix =
1102  SkMatrix::MakeAll(scale[0], skew[0], translation[0], //
1103  skew[1], scale[1], translation[1], //
1104  0, 0, 1);
1105 
1106  if (enable) {
1107  switch (selected_matrix_type) {
1108  case 0: {
1109  auto filter = flutter::DlMatrixImageFilter(
1110  filter_matrix, flutter::DlImageSampling::kLinear);
1111  paint.setImageFilter(&filter);
1112  break;
1113  }
1114  case 1: {
1115  auto internal_filter =
1116  flutter::DlBlurImageFilter(10, 10, flutter::DlTileMode::kDecal)
1117  .shared();
1118  auto filter = flutter::DlLocalMatrixImageFilter(filter_matrix,
1119  internal_filter);
1120  paint.setImageFilter(&filter);
1121  break;
1122  }
1123  }
1124  }
1125 
1126  builder.DrawImage(DlImageImpeller::Make(boston), {},
1127  flutter::DlImageSampling::kLinear, &paint);
1128  }
1129  if (enable_savelayer) {
1130  builder.Restore();
1131  }
1132 
1133  return builder.Build();
1134  };
1135 
1136  ASSERT_TRUE(OpenPlaygroundHere(callback));
1137 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [242/384]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithMatrixFilterWhenSavingLayer   
)

Definition at line 1139 of file dl_unittests.cc.

1139  {
1140  auto callback = [&]() {
1141  static float translation[2] = {0, 0};
1142  static bool enable_save_layer = true;
1143 
1144  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1145  ImGui::SliderFloat2("Translation", translation, -130, 130);
1146  ImGui::Checkbox("Enable save layer", &enable_save_layer);
1147  ImGui::End();
1148 
1149  flutter::DisplayListBuilder builder;
1150  builder.Save();
1151  builder.Scale(2.0, 2.0);
1152  flutter::DlPaint paint;
1153  paint.setColor(flutter::DlColor::kYellow());
1154  builder.DrawRect(SkRect::MakeWH(300, 300), paint);
1155  paint.setStrokeWidth(1.0);
1156  paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
1157  paint.setColor(flutter::DlColor::kBlack().withAlpha(0x80));
1158  builder.DrawLine(SkPoint::Make(150, 0), SkPoint::Make(150, 300), paint);
1159  builder.DrawLine(SkPoint::Make(0, 150), SkPoint::Make(300, 150), paint);
1160 
1161  flutter::DlPaint save_paint;
1162  SkRect bounds = SkRect::MakeXYWH(100, 100, 100, 100);
1163  SkMatrix translate_matrix =
1164  SkMatrix::Translate(translation[0], translation[1]);
1165  if (enable_save_layer) {
1166  auto filter = flutter::DlMatrixImageFilter(
1167  translate_matrix, flutter::DlImageSampling::kNearestNeighbor);
1168  save_paint.setImageFilter(filter.shared());
1169  builder.SaveLayer(&bounds, &save_paint);
1170  } else {
1171  builder.Save();
1172  builder.Transform(translate_matrix);
1173  }
1174 
1175  SkMatrix filter_matrix = SkMatrix::I();
1176  filter_matrix.postTranslate(-150, -150);
1177  filter_matrix.postScale(0.2f, 0.2f);
1178  filter_matrix.postTranslate(150, 150);
1179  auto filter = flutter::DlMatrixImageFilter(
1180  filter_matrix, flutter::DlImageSampling::kNearestNeighbor);
1181 
1182  save_paint.setImageFilter(filter.shared());
1183 
1184  builder.SaveLayer(&bounds, &save_paint);
1185  flutter::DlPaint paint2;
1186  paint2.setColor(flutter::DlColor::kBlue());
1187  builder.DrawRect(bounds, paint2);
1188  builder.Restore();
1189  builder.Restore();
1190  return builder.Build();
1191  };
1192 
1193  ASSERT_TRUE(OpenPlaygroundHere(callback));
1194 }

◆ TEST_P() [243/384]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithOddPathWinding   
)

Definition at line 398 of file dl_unittests.cc.

398  {
399  flutter::DisplayListBuilder builder;
400  flutter::DlPaint paint;
401 
402  paint.setColor(flutter::DlColor::kRed());
403  paint.setDrawStyle(flutter::DlDrawStyle::kFill);
404 
405  builder.Translate(300, 300);
406  SkPath path;
407  path.setFillType(SkPathFillType::kEvenOdd);
408  path.addCircle(0, 0, 100);
409  path.addCircle(0, 0, 50);
410  builder.DrawPath(path, paint);
411 
412  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
413 }

◆ TEST_P() [244/384]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawZeroLengthLine   
)

Definition at line 840 of file dl_unittests.cc.

840  {
841  flutter::DisplayListBuilder builder;
842  std::vector<flutter::DlStrokeCap> caps = {
843  flutter::DlStrokeCap::kButt,
844  flutter::DlStrokeCap::kRound,
845  flutter::DlStrokeCap::kSquare,
846  };
847  flutter::DlPaint paint =
848  flutter::DlPaint() //
849  .setColor(flutter::DlColor::kYellow().withAlpha(127)) //
850  .setDrawStyle(flutter::DlDrawStyle::kStroke) //
851  .setStrokeCap(flutter::DlStrokeCap::kButt) //
852  .setStrokeWidth(20);
853  SkPath path = SkPath().addPoly({{150, 50}, {150, 50}}, false);
854  for (auto cap : caps) {
855  paint.setStrokeCap(cap);
856  builder.DrawLine({50, 50}, {50, 50}, paint);
857  builder.DrawPath(path, paint);
858  builder.Translate(0, 150);
859  }
860  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
861 }

◆ TEST_P() [245/384]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawZeroWidthLine   
)

Definition at line 1002 of file dl_unittests.cc.

1002  {
1003  flutter::DisplayListBuilder builder;
1004  std::vector<flutter::DlStrokeCap> caps = {
1005  flutter::DlStrokeCap::kButt,
1006  flutter::DlStrokeCap::kRound,
1007  flutter::DlStrokeCap::kSquare,
1008  };
1009  flutter::DlPaint paint = //
1010  flutter::DlPaint() //
1011  .setColor(flutter::DlColor::kWhite()) //
1012  .setDrawStyle(flutter::DlDrawStyle::kStroke) //
1013  .setStrokeWidth(0);
1014  flutter::DlPaint outline_paint = //
1015  flutter::DlPaint() //
1016  .setColor(flutter::DlColor::kYellow()) //
1017  .setDrawStyle(flutter::DlDrawStyle::kStroke) //
1018  .setStrokeCap(flutter::DlStrokeCap::kSquare) //
1019  .setStrokeWidth(1);
1020  SkPath path = SkPath().addPoly({{150, 50}, {160, 50}}, false);
1021  for (auto cap : caps) {
1022  paint.setStrokeCap(cap);
1023  builder.DrawLine({50, 50}, {60, 50}, paint);
1024  builder.DrawRect({45, 45, 65, 55}, outline_paint);
1025  builder.DrawLine({100, 50}, {100, 50}, paint);
1026  if (cap != flutter::DlStrokeCap::kButt) {
1027  builder.DrawRect({95, 45, 105, 55}, outline_paint);
1028  }
1029  builder.DrawPath(path, paint);
1030  builder.DrawRect(path.getBounds().makeOutset(5, 5), outline_paint);
1031  builder.Translate(0, 150);
1032  }
1033  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1034 }

◆ TEST_P() [246/384]

impeller::testing::TEST_P ( DisplayListTest  ,
ClipDrawRRectWithNonCircularRadii   
)

Definition at line 1594 of file dl_unittests.cc.

1594  {
1595  flutter::DisplayListBuilder builder;
1596 
1597  flutter::DlPaint fill_paint = //
1598  flutter::DlPaint() //
1599  .setColor(flutter::DlColor::kBlue()) //
1600  .setDrawStyle(flutter::DlDrawStyle::kFill) //
1601  .setStrokeWidth(10);
1602  flutter::DlPaint stroke_paint = //
1603  flutter::DlPaint() //
1604  .setColor(flutter::DlColor::kGreen()) //
1605  .setDrawStyle(flutter::DlDrawStyle::kStroke) //
1606  .setStrokeWidth(10);
1607 
1608  builder.DrawRRect(
1609  SkRRect::MakeRectXY(SkRect::MakeXYWH(500, 100, 300, 300), 120, 40),
1610  fill_paint);
1611  builder.DrawRRect(
1612  SkRRect::MakeRectXY(SkRect::MakeXYWH(500, 100, 300, 300), 120, 40),
1613  stroke_paint);
1614 
1615  builder.DrawRRect(
1616  SkRRect::MakeRectXY(SkRect::MakeXYWH(100, 500, 300, 300), 40, 120),
1617  fill_paint);
1618  builder.DrawRRect(
1619  SkRRect::MakeRectXY(SkRect::MakeXYWH(100, 500, 300, 300), 40, 120),
1620  stroke_paint);
1621 
1622  flutter::DlPaint reference_paint = //
1623  flutter::DlPaint() //
1624  .setColor(flutter::DlColor::kMidGrey()) //
1625  .setDrawStyle(flutter::DlDrawStyle::kFill) //
1626  .setStrokeWidth(10);
1627 
1628  builder.DrawRRect(
1629  SkRRect::MakeRectXY(SkRect::MakeXYWH(500, 500, 300, 300), 40, 40),
1630  reference_paint);
1631  builder.DrawRRect(
1632  SkRRect::MakeRectXY(SkRect::MakeXYWH(100, 100, 300, 300), 120, 120),
1633  reference_paint);
1634 
1635  flutter::DlPaint clip_fill_paint = //
1636  flutter::DlPaint() //
1637  .setColor(flutter::DlColor::kCyan()) //
1638  .setDrawStyle(flutter::DlDrawStyle::kFill) //
1639  .setStrokeWidth(10);
1640 
1641  builder.Save();
1642  builder.ClipRRect(
1643  SkRRect::MakeRectXY(SkRect::MakeXYWH(900, 100, 300, 300), 120, 40));
1644  builder.DrawPaint(clip_fill_paint);
1645  builder.Restore();
1646 
1647  builder.Save();
1648  builder.ClipRRect(
1649  SkRRect::MakeRectXY(SkRect::MakeXYWH(100, 900, 300, 300), 40, 120));
1650  builder.DrawPaint(clip_fill_paint);
1651  builder.Restore();
1652 
1653  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1654 }

◆ TEST_P() [247/384]

impeller::testing::TEST_P ( DisplayListTest  ,
DispatcherDoesNotCullPerspectiveTransformedChildDisplayLists   
)

Definition at line 912 of file dl_unittests.cc.

913  {
914  // Regression test for https://github.com/flutter/flutter/issues/130613
915  flutter::DisplayListBuilder sub_builder(true);
916  sub_builder.DrawRect(SkRect::MakeXYWH(0, 0, 50, 50),
917  flutter::DlPaint(flutter::DlColor::kRed()));
918  auto display_list = sub_builder.Build();
919 
920  DlDispatcher dispatcher(Rect::MakeLTRB(0, 0, 2400, 1800));
921  dispatcher.scale(2.0, 2.0);
922  dispatcher.translate(-93.0, 0.0);
923  // clang-format off
924  dispatcher.transformFullPerspective(
925  0.8, -0.2, -0.1, -0.0,
926  0.0, 1.0, 0.0, 0.0,
927  1.4, 1.3, 1.0, 0.0,
928  63.2, 65.3, 48.6, 1.1
929  );
930  // clang-format on
931  dispatcher.translate(35.0, 75.0);
932  dispatcher.drawDisplayList(display_list, 1.0f);
933  auto picture = dispatcher.EndRecordingAsPicture();
934 
935  bool found = false;
936  picture.pass->IterateAllEntities([&found](Entity& entity) {
937  if (std::static_pointer_cast<SolidColorContents>(entity.GetContents())
938  ->GetColor() == Color::Red()) {
939  found = true;
940  return false;
941  }
942 
943  return true;
944  });
945  EXPECT_TRUE(found);
946 }

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() [248/384]

impeller::testing::TEST_P ( DisplayListTest  ,
DrawPictureWithAClip   
)

Definition at line 49 of file dl_unittests.cc.

49  {
50  flutter::DisplayListBuilder sub_builder;
51  sub_builder.ClipRect(SkRect::MakeXYWH(0, 0, 24, 24));
52  sub_builder.DrawPaint(flutter::DlPaint(flutter::DlColor::kBlue()));
53 
54  auto display_list = sub_builder.Build();
55  flutter::DisplayListBuilder builder;
56  builder.DrawDisplayList(display_list);
57  builder.DrawRect(SkRect::MakeXYWH(30, 30, 24, 24),
58  flutter::DlPaint(flutter::DlColor::kRed()));
59  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
60 }

◆ TEST_P() [249/384]

impeller::testing::TEST_P ( DisplayListTest  ,
DrawShapes   
)

Definition at line 1556 of file dl_unittests.cc.

1556  {
1557  flutter::DisplayListBuilder builder;
1558  std::vector<flutter::DlStrokeJoin> joins = {
1559  flutter::DlStrokeJoin::kBevel,
1560  flutter::DlStrokeJoin::kRound,
1561  flutter::DlStrokeJoin::kMiter,
1562  };
1563  flutter::DlPaint paint = //
1564  flutter::DlPaint() //
1565  .setColor(flutter::DlColor::kWhite()) //
1566  .setDrawStyle(flutter::DlDrawStyle::kFill) //
1567  .setStrokeWidth(10);
1568  flutter::DlPaint stroke_paint = //
1569  flutter::DlPaint() //
1570  .setColor(flutter::DlColor::kWhite()) //
1571  .setDrawStyle(flutter::DlDrawStyle::kStroke) //
1572  .setStrokeWidth(10);
1573  SkPath path = SkPath().addPoly({{150, 50}, {160, 50}}, false);
1574 
1575  builder.Translate(300, 50);
1576  builder.Scale(0.8, 0.8);
1577  for (auto join : joins) {
1578  paint.setStrokeJoin(join);
1579  stroke_paint.setStrokeJoin(join);
1580  builder.DrawRect(SkRect::MakeXYWH(0, 0, 100, 100), paint);
1581  builder.DrawRect(SkRect::MakeXYWH(0, 150, 100, 100), stroke_paint);
1582  builder.DrawRRect(
1583  SkRRect::MakeRectXY(SkRect::MakeXYWH(150, 0, 100, 100), 30, 30), paint);
1584  builder.DrawRRect(
1585  SkRRect::MakeRectXY(SkRect::MakeXYWH(150, 150, 100, 100), 30, 30),
1586  stroke_paint);
1587  builder.DrawCircle({350, 50}, 50, paint);
1588  builder.DrawCircle({350, 200}, 50, stroke_paint);
1589  builder.Translate(0, 300);
1590  }
1591  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1592 }

◆ TEST_P() [250/384]

impeller::testing::TEST_P ( DisplayListTest  ,
DrawVerticesBlendModes   
)

Definition at line 1656 of file dl_unittests.cc.

1656  {
1657  std::vector<const char*> blend_mode_names;
1658  std::vector<flutter::DlBlendMode> blend_mode_values;
1659  {
1660  const std::vector<std::tuple<const char*, flutter::DlBlendMode>> blends = {
1661  // Pipeline blends (Porter-Duff alpha compositing)
1662  {"Clear", flutter::DlBlendMode::kClear},
1663  {"Source", flutter::DlBlendMode::kSrc},
1664  {"Destination", flutter::DlBlendMode::kDst},
1665  {"SourceOver", flutter::DlBlendMode::kSrcOver},
1666  {"DestinationOver", flutter::DlBlendMode::kDstOver},
1667  {"SourceIn", flutter::DlBlendMode::kSrcIn},
1668  {"DestinationIn", flutter::DlBlendMode::kDstIn},
1669  {"SourceOut", flutter::DlBlendMode::kSrcOut},
1670  {"DestinationOut", flutter::DlBlendMode::kDstOut},
1671  {"SourceATop", flutter::DlBlendMode::kSrcATop},
1672  {"DestinationATop", flutter::DlBlendMode::kDstATop},
1673  {"Xor", flutter::DlBlendMode::kXor},
1674  {"Plus", flutter::DlBlendMode::kPlus},
1675  {"Modulate", flutter::DlBlendMode::kModulate},
1676  // Advanced blends (color component blends)
1677  {"Screen", flutter::DlBlendMode::kScreen},
1678  {"Overlay", flutter::DlBlendMode::kOverlay},
1679  {"Darken", flutter::DlBlendMode::kDarken},
1680  {"Lighten", flutter::DlBlendMode::kLighten},
1681  {"ColorDodge", flutter::DlBlendMode::kColorDodge},
1682  {"ColorBurn", flutter::DlBlendMode::kColorBurn},
1683  {"HardLight", flutter::DlBlendMode::kHardLight},
1684  {"SoftLight", flutter::DlBlendMode::kSoftLight},
1685  {"Difference", flutter::DlBlendMode::kDifference},
1686  {"Exclusion", flutter::DlBlendMode::kExclusion},
1687  {"Multiply", flutter::DlBlendMode::kMultiply},
1688  {"Hue", flutter::DlBlendMode::kHue},
1689  {"Saturation", flutter::DlBlendMode::kSaturation},
1690  {"Color", flutter::DlBlendMode::kColor},
1691  {"Luminosity", flutter::DlBlendMode::kLuminosity},
1692  };
1693  assert(blends.size() ==
1694  static_cast<size_t>(flutter::DlBlendMode::kLastMode) + 1);
1695  for (const auto& [name, mode] : blends) {
1696  blend_mode_names.push_back(name);
1697  blend_mode_values.push_back(mode);
1698  }
1699  }
1700 
1701  auto callback = [&]() {
1702  static int current_blend_index = 3;
1703  static float dst_alpha = 1;
1704  static float src_alpha = 1;
1705  static float color0[4] = {1.0f, 0.0f, 0.0f, 1.0f};
1706  static float color1[4] = {0.0f, 1.0f, 0.0f, 1.0f};
1707  static float color2[4] = {0.0f, 0.0f, 1.0f, 1.0f};
1708  static float src_color[4] = {1.0f, 1.0f, 1.0f, 1.0f};
1709 
1710  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1711  {
1712  ImGui::ListBox("Blending mode", &current_blend_index,
1713  blend_mode_names.data(), blend_mode_names.size());
1714  ImGui::SliderFloat("Source alpha", &src_alpha, 0, 1);
1715  ImGui::ColorEdit4("Color A", color0);
1716  ImGui::ColorEdit4("Color B", color1);
1717  ImGui::ColorEdit4("Color C", color2);
1718  ImGui::ColorEdit4("Source Color", src_color);
1719  ImGui::SliderFloat("Destination alpha", &dst_alpha, 0, 1);
1720  }
1721  ImGui::End();
1722 
1723  std::vector<SkPoint> positions = {SkPoint::Make(100, 300),
1724  SkPoint::Make(200, 100),
1725  SkPoint::Make(300, 300)};
1726  std::vector<flutter::DlColor> colors = {
1727  toColor(color0).modulateOpacity(dst_alpha),
1728  toColor(color1).modulateOpacity(dst_alpha),
1729  toColor(color2).modulateOpacity(dst_alpha)};
1730 
1731  auto vertices = flutter::DlVertices::Make(
1732  flutter::DlVertexMode::kTriangles, 3, positions.data(),
1733  /*texture_coordinates=*/nullptr, colors.data());
1734 
1735  flutter::DisplayListBuilder builder;
1736  flutter::DlPaint paint;
1737 
1738  paint.setColor(toColor(src_color).modulateOpacity(src_alpha));
1739  builder.DrawVertices(vertices, blend_mode_values[current_blend_index],
1740  paint);
1741  return builder.Build();
1742  };
1743 
1744  ASSERT_TRUE(OpenPlaygroundHere(callback));
1745 }

References impeller::kColor, and toColor().

◆ TEST_P() [251/384]

impeller::testing::TEST_P ( DisplayListTest  ,
DrawVerticesImageSourceWithTextureCoordinates   
)

Definition at line 1460 of file dl_unittests.cc.

1460  {
1461  auto texture = CreateTextureForFixture("embarcadero.jpg");
1462  auto dl_image = DlImageImpeller::Make(texture);
1463  std::vector<SkPoint> positions = {SkPoint::Make(100, 300),
1464  SkPoint::Make(200, 100),
1465  SkPoint::Make(300, 300)};
1466  std::vector<SkPoint> texture_coordinates = {
1467  SkPoint::Make(0, 0), SkPoint::Make(100, 200), SkPoint::Make(200, 100)};
1468 
1469  auto vertices = flutter::DlVertices::Make(
1470  flutter::DlVertexMode::kTriangles, 3, positions.data(),
1471  texture_coordinates.data(), /*colors=*/nullptr);
1472 
1473  flutter::DisplayListBuilder builder;
1474  flutter::DlPaint paint;
1475 
1476  auto image_source = flutter::DlImageColorSource(
1477  dl_image, flutter::DlTileMode::kRepeat, flutter::DlTileMode::kRepeat);
1478 
1479  paint.setColorSource(&image_source);
1480  builder.DrawVertices(vertices, flutter::DlBlendMode::kSrcOver, paint);
1481 
1482  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1483 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [252/384]

impeller::testing::TEST_P ( DisplayListTest  ,
DrawVerticesImageSourceWithTextureCoordinatesAndColorBlending   
)

Definition at line 1485 of file dl_unittests.cc.

1486  {
1487  auto texture = CreateTextureForFixture("embarcadero.jpg");
1488  auto dl_image = DlImageImpeller::Make(texture);
1489  std::vector<SkPoint> positions = {SkPoint::Make(100, 300),
1490  SkPoint::Make(200, 100),
1491  SkPoint::Make(300, 300)};
1492  std::vector<flutter::DlColor> colors = {flutter::DlColor::kWhite(),
1493  flutter::DlColor::kGreen(),
1494  flutter::DlColor::kWhite()};
1495  std::vector<SkPoint> texture_coordinates = {
1496  SkPoint::Make(0, 0), SkPoint::Make(100, 200), SkPoint::Make(200, 100)};
1497 
1498  auto vertices = flutter::DlVertices::Make(
1499  flutter::DlVertexMode::kTriangles, 3, positions.data(),
1500  texture_coordinates.data(), colors.data());
1501 
1502  flutter::DisplayListBuilder builder;
1503  flutter::DlPaint paint;
1504 
1505  auto image_source = flutter::DlImageColorSource(
1506  dl_image, flutter::DlTileMode::kRepeat, flutter::DlTileMode::kRepeat);
1507 
1508  paint.setColorSource(&image_source);
1509  builder.DrawVertices(vertices, flutter::DlBlendMode::kModulate, paint);
1510 
1511  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1512 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [253/384]

impeller::testing::TEST_P ( DisplayListTest  ,
DrawVerticesLinearGradientWithoutIndices   
)

Definition at line 1405 of file dl_unittests.cc.

1405  {
1406  std::vector<SkPoint> positions = {SkPoint::Make(100, 300),
1407  SkPoint::Make(200, 100),
1408  SkPoint::Make(300, 300)};
1409 
1410  auto vertices = flutter::DlVertices::Make(
1411  flutter::DlVertexMode::kTriangles, 3, positions.data(),
1412  /*texture_coordinates=*/nullptr, /*colors=*/nullptr);
1413 
1414  std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
1415  flutter::DlColor::kRed()};
1416  const float stops[2] = {0.0, 1.0};
1417 
1418  auto linear = flutter::DlColorSource::MakeLinear(
1419  {100.0, 100.0}, {300.0, 300.0}, 2, colors.data(), stops,
1420  flutter::DlTileMode::kRepeat);
1421 
1422  flutter::DisplayListBuilder builder;
1423  flutter::DlPaint paint;
1424 
1425  paint.setColorSource(linear);
1426  builder.DrawVertices(vertices, flutter::DlBlendMode::kSrcOver, paint);
1427 
1428  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1429 }

◆ TEST_P() [254/384]

impeller::testing::TEST_P ( DisplayListTest  ,
DrawVerticesLinearGradientWithTextureCoordinates   
)

Definition at line 1431 of file dl_unittests.cc.

1431  {
1432  std::vector<SkPoint> positions = {SkPoint::Make(100, 300),
1433  SkPoint::Make(200, 100),
1434  SkPoint::Make(300, 300)};
1435  std::vector<SkPoint> texture_coordinates = {SkPoint::Make(300, 100),
1436  SkPoint::Make(100, 200),
1437  SkPoint::Make(300, 300)};
1438 
1439  auto vertices = flutter::DlVertices::Make(
1440  flutter::DlVertexMode::kTriangles, 3, positions.data(),
1441  texture_coordinates.data(), /*colors=*/nullptr);
1442 
1443  std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
1444  flutter::DlColor::kRed()};
1445  const float stops[2] = {0.0, 1.0};
1446 
1447  auto linear = flutter::DlColorSource::MakeLinear(
1448  {100.0, 100.0}, {300.0, 300.0}, 2, colors.data(), stops,
1449  flutter::DlTileMode::kRepeat);
1450 
1451  flutter::DisplayListBuilder builder;
1452  flutter::DlPaint paint;
1453 
1454  paint.setColorSource(linear);
1455  builder.DrawVertices(vertices, flutter::DlBlendMode::kSrcOver, paint);
1456 
1457  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1458 }

◆ TEST_P() [255/384]

impeller::testing::TEST_P ( DisplayListTest  ,
DrawVerticesPremultipliesColors   
)

Definition at line 1533 of file dl_unittests.cc.

1533  {
1534  std::vector<SkPoint> positions = {
1535  SkPoint::Make(100, 300), SkPoint::Make(200, 100), SkPoint::Make(300, 300),
1536  SkPoint::Make(200, 500)};
1537  auto color = flutter::DlColor::kBlue().withAlpha(0x99);
1538  std::vector<uint16_t> indices = {0, 1, 2, 0, 2, 3};
1539  std::vector<flutter::DlColor> colors = {color, color, color, color};
1540 
1541  auto vertices = flutter::DlVertices::Make(
1542  flutter::DlVertexMode::kTriangles, 6, positions.data(),
1543  /*texture_coordinates=*/nullptr, colors.data(), 6, indices.data());
1544 
1545  flutter::DisplayListBuilder builder;
1546  flutter::DlPaint paint;
1547  paint.setBlendMode(flutter::DlBlendMode::kSrcOver);
1548  paint.setColor(flutter::DlColor::kRed());
1549 
1550  builder.DrawRect(SkRect::MakeLTRB(0, 0, 400, 400), paint);
1551  builder.DrawVertices(vertices, flutter::DlBlendMode::kDst, paint);
1552 
1553  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1554 }

◆ TEST_P() [256/384]

impeller::testing::TEST_P ( DisplayListTest  ,
DrawVerticesSolidColorTrianglesWithIndices   
)

Definition at line 1514 of file dl_unittests.cc.

1514  {
1515  std::vector<SkPoint> positions = {
1516  SkPoint::Make(100, 300), SkPoint::Make(200, 100), SkPoint::Make(300, 300),
1517  SkPoint::Make(200, 500)};
1518  std::vector<uint16_t> indices = {0, 1, 2, 0, 2, 3};
1519 
1520  auto vertices = flutter::DlVertices::Make(
1521  flutter::DlVertexMode::kTriangles, 6, positions.data(),
1522  /*texture_coordinates=*/nullptr, /*colors=*/nullptr, 6, indices.data());
1523 
1524  flutter::DisplayListBuilder builder;
1525  flutter::DlPaint paint;
1526 
1527  paint.setColor(flutter::DlColor::kWhite());
1528  builder.DrawVertices(vertices, flutter::DlBlendMode::kSrcOver, paint);
1529 
1530  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1531 }

◆ TEST_P() [257/384]

impeller::testing::TEST_P ( DisplayListTest  ,
DrawVerticesSolidColorTrianglesWithoutIndices   
)

Definition at line 1381 of file dl_unittests.cc.

1381  {
1382  // Use negative coordinates and then scale the transform by -1, -1 to make
1383  // sure coverage is taking the transform into account.
1384  std::vector<SkPoint> positions = {SkPoint::Make(-100, -300),
1385  SkPoint::Make(-200, -100),
1386  SkPoint::Make(-300, -300)};
1387  std::vector<flutter::DlColor> colors = {flutter::DlColor::kWhite(),
1388  flutter::DlColor::kGreen(),
1389  flutter::DlColor::kWhite()};
1390 
1391  auto vertices = flutter::DlVertices::Make(
1392  flutter::DlVertexMode::kTriangles, 3, positions.data(),
1393  /*texture_coordinates=*/nullptr, colors.data());
1394 
1395  flutter::DisplayListBuilder builder;
1396  flutter::DlPaint paint;
1397 
1398  paint.setColor(flutter::DlColor::kRed().modulateOpacity(0.5));
1399  builder.Scale(-1, -1);
1400  builder.DrawVertices(vertices, flutter::DlBlendMode::kSrcOver, paint);
1401 
1402  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1403 }

◆ TEST_P() [258/384]

impeller::testing::TEST_P ( DisplayListTest  ,
IgnoreMaskFilterWhenSavingLayer   
)

Definition at line 517 of file dl_unittests.cc.

517  {
518  auto texture = CreateTextureForFixture("embarcadero.jpg");
519  flutter::DisplayListBuilder builder;
520  auto filter = flutter::DlBlurMaskFilter(flutter::DlBlurStyle::kNormal, 10.0f);
521  flutter::DlPaint paint;
522  paint.setMaskFilter(&filter);
523  builder.SaveLayer(nullptr, &paint);
524  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
525  flutter::DlImageSampling::kNearestNeighbor);
526  builder.Restore();
527  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
528 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [259/384]

impeller::testing::TEST_P ( DisplayListTest  ,
MaskBlursApplyCorrectlyToColorSources   
)

Definition at line 1344 of file dl_unittests.cc.

1344  {
1345  auto blur_filter = std::make_shared<flutter::DlBlurMaskFilter>(
1346  flutter::DlBlurStyle::kNormal, 10);
1347 
1348  flutter::DisplayListBuilder builder;
1349 
1350  std::array<flutter::DlColor, 2> colors = {flutter::DlColor::kBlue(),
1351  flutter::DlColor::kGreen()};
1352  std::array<float, 2> stops = {0, 1};
1353  std::array<std::shared_ptr<flutter::DlColorSource>, 2> color_sources = {
1354  std::make_shared<flutter::DlColorColorSource>(flutter::DlColor::kWhite()),
1355  flutter::DlColorSource::MakeLinear(
1356  SkPoint::Make(0, 0), SkPoint::Make(100, 50), 2, colors.data(),
1357  stops.data(), flutter::DlTileMode::kClamp)};
1358 
1359  int offset = 100;
1360  for (const auto& color_source : color_sources) {
1361  flutter::DlPaint paint;
1362  paint.setColorSource(color_source);
1363  paint.setMaskFilter(blur_filter);
1364 
1365  paint.setDrawStyle(flutter::DlDrawStyle::kFill);
1366  builder.DrawRRect(
1367  SkRRect::MakeRectXY(SkRect::MakeXYWH(100, offset, 100, 50), 30, 30),
1368  paint);
1369  paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
1370  paint.setStrokeWidth(10);
1371  builder.DrawRRect(
1372  SkRRect::MakeRectXY(SkRect::MakeXYWH(300, offset, 100, 50), 30, 30),
1373  paint);
1374 
1375  offset += 100;
1376  }
1377 
1378  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1379 }

◆ TEST_P() [260/384]

impeller::testing::TEST_P ( DisplayListTest  ,
StrokedPathsDrawCorrectly   
)

Definition at line 225 of file dl_unittests.cc.

225  {
226  auto callback = [&]() {
227  flutter::DisplayListBuilder builder;
228  flutter::DlPaint paint;
229 
230  paint.setColor(flutter::DlColor::kRed());
231  paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
232 
233  static float stroke_width = 10.0f;
234  static int selected_stroke_type = 0;
235  static int selected_join_type = 0;
236  const char* stroke_types[] = {"Butte", "Round", "Square"};
237  const char* join_type[] = {"kMiter", "Round", "kBevel"};
238 
239  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
240  ImGui::Combo("Cap", &selected_stroke_type, stroke_types,
241  sizeof(stroke_types) / sizeof(char*));
242  ImGui::Combo("Join", &selected_join_type, join_type,
243  sizeof(join_type) / sizeof(char*));
244  ImGui::SliderFloat("Stroke Width", &stroke_width, 10.0f, 50.0f);
245  ImGui::End();
246 
247  flutter::DlStrokeCap cap;
248  flutter::DlStrokeJoin join;
249  switch (selected_stroke_type) {
250  case 0:
251  cap = flutter::DlStrokeCap::kButt;
252  break;
253  case 1:
254  cap = flutter::DlStrokeCap::kRound;
255  break;
256  case 2:
257  cap = flutter::DlStrokeCap::kSquare;
258  break;
259  default:
260  cap = flutter::DlStrokeCap::kButt;
261  break;
262  }
263  switch (selected_join_type) {
264  case 0:
265  join = flutter::DlStrokeJoin::kMiter;
266  break;
267  case 1:
268  join = flutter::DlStrokeJoin::kRound;
269  break;
270  case 2:
271  join = flutter::DlStrokeJoin::kBevel;
272  break;
273  default:
274  join = flutter::DlStrokeJoin::kMiter;
275  break;
276  }
277  paint.setStrokeCap(cap);
278  paint.setStrokeJoin(join);
279  paint.setStrokeWidth(stroke_width);
280 
281  // Make rendering better to watch.
282  builder.Scale(1.5f, 1.5f);
283 
284  // Rectangle
285  builder.Translate(100, 100);
286  builder.DrawRect(SkRect::MakeSize({100, 100}), paint);
287 
288  // Rounded rectangle
289  builder.Translate(150, 0);
290  builder.DrawRRect(SkRRect::MakeRectXY(SkRect::MakeSize({100, 50}), 10, 10),
291  paint);
292 
293  // Double rounded rectangle
294  builder.Translate(150, 0);
295  builder.DrawDRRect(
296  SkRRect::MakeRectXY(SkRect::MakeSize({100, 50}), 10, 10),
297  SkRRect::MakeRectXY(SkRect::MakeXYWH(10, 10, 80, 30), 10, 10), paint);
298 
299  // Contour with duplicate join points
300  {
301  builder.Translate(150, 0);
302  SkPath path;
303  path.moveTo(0, 0);
304  path.lineTo(0, 0);
305  path.lineTo({100, 0});
306  path.lineTo({100, 0});
307  path.lineTo({100, 100});
308  builder.DrawPath(path, paint);
309  }
310 
311  // Contour with duplicate start and end points
312 
313  // Line.
314  builder.Translate(200, 0);
315  {
316  builder.Save();
317 
318  SkPath line_path;
319  line_path.moveTo(0, 0);
320  line_path.moveTo(0, 0);
321  line_path.lineTo({0, 0});
322  line_path.lineTo({0, 0});
323  line_path.lineTo({50, 50});
324  line_path.lineTo({50, 50});
325  line_path.lineTo({100, 0});
326  line_path.lineTo({100, 0});
327  builder.DrawPath(line_path, paint);
328 
329  builder.Translate(0, 100);
330  builder.DrawPath(line_path, paint);
331 
332  builder.Translate(0, 100);
333  SkPath line_path2;
334  line_path2.moveTo(0, 0);
335  line_path2.lineTo(0, 0);
336  line_path2.lineTo(0, 0);
337  builder.DrawPath(line_path2, paint);
338 
339  builder.Restore();
340  }
341 
342  // Cubic.
343  builder.Translate(150, 0);
344  {
345  builder.Save();
346 
347  SkPath cubic_path;
348  cubic_path.moveTo({0, 0});
349  cubic_path.cubicTo(0, 0, 140.0, 100.0, 140, 20);
350  builder.DrawPath(cubic_path, paint);
351 
352  builder.Translate(0, 100);
353  SkPath cubic_path2;
354  cubic_path2.moveTo({0, 0});
355  cubic_path2.cubicTo(0, 0, 0, 0, 150, 150);
356  builder.DrawPath(cubic_path2, paint);
357 
358  builder.Translate(0, 100);
359  SkPath cubic_path3;
360  cubic_path3.moveTo({0, 0});
361  cubic_path3.cubicTo(0, 0, 0, 0, 0, 0);
362  builder.DrawPath(cubic_path3, paint);
363 
364  builder.Restore();
365  }
366 
367  // Quad.
368  builder.Translate(200, 0);
369  {
370  builder.Save();
371 
372  SkPath quad_path;
373  quad_path.moveTo(0, 0);
374  quad_path.moveTo(0, 0);
375  quad_path.quadTo({100, 40}, {50, 80});
376  builder.DrawPath(quad_path, paint);
377 
378  builder.Translate(0, 150);
379  SkPath quad_path2;
380  quad_path2.moveTo(0, 0);
381  quad_path2.moveTo(0, 0);
382  quad_path2.quadTo({0, 0}, {100, 100});
383  builder.DrawPath(quad_path2, paint);
384 
385  builder.Translate(0, 100);
386  SkPath quad_path3;
387  quad_path3.moveTo(0, 0);
388  quad_path3.quadTo({0, 0}, {0, 0});
389  builder.DrawPath(quad_path3, paint);
390 
391  builder.Restore();
392  }
393  return builder.Build();
394  };
395  ASSERT_TRUE(OpenPlaygroundHere(callback));
396 }

◆ TEST_P() [261/384]

impeller::testing::TEST_P ( DisplayListTest  ,
StrokedTextNotOffsetFromNormalText   
)

Definition at line 492 of file dl_unittests.cc.

492  {
493  flutter::DisplayListBuilder builder;
494  flutter::DlPaint paint;
495  auto const& text_blob = SkTextBlob::MakeFromString("00000", CreateTestFont());
496 
497  // https://api.flutter.dev/flutter/material/Colors/blue-constant.html.
498  auto const& mat_blue = flutter::DlColor(0xFF2196f3);
499 
500  // Draw a blue filled rectangle so the text is easier to see.
501  paint.setDrawStyle(flutter::DlDrawStyle::kFill);
502  paint.setColor(mat_blue);
503  builder.DrawRect(SkRect::MakeXYWH(0, 0, 500, 500), paint);
504 
505  // Draw stacked text, with stroked text on top.
506  paint.setDrawStyle(flutter::DlDrawStyle::kFill);
507  paint.setColor(flutter::DlColor::kWhite());
508  builder.DrawTextBlob(text_blob, 250, 250, paint);
509 
510  paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
511  paint.setColor(flutter::DlColor::kBlack());
512  builder.DrawTextBlob(text_blob, 250, 250, paint);
513 
514  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
515 }

◆ TEST_P() [262/384]

impeller::testing::TEST_P ( DisplayListTest  ,
TransparentShadowProducesCorrectColor   
)

Definition at line 948 of file dl_unittests.cc.

948  {
949  DlDispatcher dispatcher;
950  dispatcher.save();
951  dispatcher.scale(1.618, 1.618);
952  dispatcher.drawShadow(SkPath{}.addRect(SkRect::MakeXYWH(0, 0, 200, 100)),
953  flutter::DlColor::kTransparent(), 15, false, 1);
954  dispatcher.restore();
955  auto picture = dispatcher.EndRecordingAsPicture();
956 
957  std::shared_ptr<SolidRRectBlurContents> rrect_blur;
958  picture.pass->IterateAllEntities([&rrect_blur](Entity& entity) {
959  if (ScalarNearlyEqual(entity.GetTransform().GetScale().x, 1.618f)) {
960  rrect_blur = std::static_pointer_cast<SolidRRectBlurContents>(
961  entity.GetContents());
962  return false;
963  }
964  return true;
965  });
966 
967  ASSERT_NE(rrect_blur, nullptr);
968  ASSERT_EQ(rrect_blur->GetColor().red, 0);
969  ASSERT_EQ(rrect_blur->GetColor().green, 0);
970  ASSERT_EQ(rrect_blur->GetColor().blue, 0);
971  ASSERT_EQ(rrect_blur->GetColor().alpha, 0);
972 }

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() [263/384]

impeller::testing::TEST_P ( EntityPassTargetTest  ,
SwapWithMSAAImplicitResolve   
)

Definition at line 52 of file entity_pass_target_unittests.cc.

52  {
53  auto content_context = GetContentContext();
54  auto buffer = content_context->GetContext()->CreateCommandBuffer();
55  auto context = content_context->GetContext();
56  auto& allocator = *context->GetResourceAllocator();
57 
58  // Emulate implicit MSAA resolve by making color resolve and msaa texture the
59  // same.
60  RenderTarget render_target;
61  {
62  PixelFormat pixel_format =
63  context->GetCapabilities()->GetDefaultColorFormat();
64 
65  // Create MSAA color texture.
66 
67  TextureDescriptor color0_tex_desc;
68  color0_tex_desc.storage_mode = StorageMode::kDevicePrivate;
69  color0_tex_desc.type = TextureType::kTexture2DMultisample;
70  color0_tex_desc.sample_count = SampleCount::kCount4;
71  color0_tex_desc.format = pixel_format;
72  color0_tex_desc.size = ISize{100, 100};
73  color0_tex_desc.usage = static_cast<uint64_t>(TextureUsage::kRenderTarget);
74 
75  auto color0_msaa_tex = allocator.CreateTexture(color0_tex_desc);
76 
77  // Color attachment.
78 
79  ColorAttachment color0;
80  color0.load_action = LoadAction::kDontCare;
81  color0.store_action = StoreAction::kStoreAndMultisampleResolve;
82  color0.texture = color0_msaa_tex;
83  color0.resolve_texture = color0_msaa_tex;
84 
85  render_target.SetColorAttachment(color0, 0u);
86  render_target.SetStencilAttachment(std::nullopt);
87  }
88 
89  auto entity_pass_target = EntityPassTarget(render_target, false, true);
90 
91  auto color0 = entity_pass_target.GetRenderTarget()
92  .GetColorAttachments()
93  .find(0u)
94  ->second;
95  auto msaa_tex = color0.texture;
96  auto resolve_tex = color0.resolve_texture;
97 
98  ASSERT_EQ(msaa_tex, resolve_tex);
99 
100  entity_pass_target.Flip(
101  *content_context->GetContext()->GetResourceAllocator());
102 
103  color0 = entity_pass_target.GetRenderTarget()
104  .GetColorAttachments()
105  .find(0u)
106  ->second;
107 
108  ASSERT_NE(msaa_tex, color0.texture);
109  ASSERT_NE(resolve_tex, color0.resolve_texture);
110  ASSERT_EQ(color0.texture, color0.resolve_texture);
111 }

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() [264/384]

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 = RenderTarget::CreateOffscreenMSAA(
28  *content_context->GetContext(),
29  *GetContentContext()->GetRenderTargetCache(), {100, 100});
30 
31  auto entity_pass_target = EntityPassTarget(render_target, false, false);
32 
33  auto color0 = entity_pass_target.GetRenderTarget()
34  .GetColorAttachments()
35  .find(0u)
36  ->second;
37  auto msaa_tex = color0.texture;
38  auto resolve_tex = color0.resolve_texture;
39 
40  entity_pass_target.Flip(
41  *content_context->GetContext()->GetResourceAllocator());
42 
43  color0 = entity_pass_target.GetRenderTarget()
44  .GetColorAttachments()
45  .find(0u)
46  ->second;
47 
48  ASSERT_EQ(msaa_tex, color0.texture);
49  ASSERT_NE(resolve_tex, color0.resolve_texture);
50 }

References impeller::RenderTarget::CreateOffscreenMSAA().

◆ TEST_P() [265/384]

impeller::testing::TEST_P ( EntityTest  ,
AdvancedBlendCoverageHintIsNotResetByEntityPass   
)

Definition at line 2484 of file entity_unittests.cc.

2484  {
2485  if (GetContext()->GetCapabilities()->SupportsFramebufferFetch()) {
2486  GTEST_SKIP() << "Backends that support framebuffer fetch dont use coverage "
2487  "for advanced blends.";
2488  }
2489 
2490  auto contents = std::make_shared<SolidColorContents>();
2491  contents->SetGeometry(Geometry::MakeRect(Rect::MakeXYWH(100, 100, 100, 100)));
2492  contents->SetColor(Color::Red());
2493 
2494  Entity entity;
2495  entity.SetTransform(Matrix::MakeScale(Vector3(2, 2, 1)));
2496  entity.SetBlendMode(BlendMode::kColorBurn);
2497  entity.SetContents(contents);
2498 
2499  auto coverage = entity.GetCoverage();
2500  EXPECT_TRUE(coverage.has_value());
2501 
2502  auto pass = std::make_unique<EntityPass>();
2503  auto test_allocator = std::make_shared<TestRenderTargetAllocator>(
2504  GetContext()->GetResourceAllocator());
2505  auto stencil_config = RenderTarget::AttachmentConfig{
2506  .storage_mode = StorageMode::kDevicePrivate,
2507  .load_action = LoadAction::kClear,
2508  .store_action = StoreAction::kDontCare,
2509  .clear_color = Color::BlackTransparent()};
2510  auto rt = RenderTarget::CreateOffscreen(
2511  *GetContext(), *test_allocator, ISize::MakeWH(1000, 1000), "Offscreen",
2512  RenderTarget::kDefaultColorAttachmentConfig, stencil_config);
2513  auto content_context = ContentContext(
2514  GetContext(), TypographerContextSkia::Make(), test_allocator);
2515  pass->AddEntity(std::move(entity));
2516 
2517  EXPECT_TRUE(pass->Render(content_context, rt));
2518 
2519  if (test_allocator->GetDescriptors().size() == 6u) {
2520  EXPECT_EQ(test_allocator->GetDescriptors()[0].size, ISize(1000, 1000));
2521  EXPECT_EQ(test_allocator->GetDescriptors()[1].size, ISize(1000, 1000));
2522 
2523  EXPECT_EQ(test_allocator->GetDescriptors()[2].size, ISize(200, 200));
2524  EXPECT_EQ(test_allocator->GetDescriptors()[3].size, ISize(200, 200));
2525  EXPECT_EQ(test_allocator->GetDescriptors()[4].size, ISize(200, 200));
2526  EXPECT_EQ(test_allocator->GetDescriptors()[5].size, ISize(200, 200));
2527  } else if (test_allocator->GetDescriptors().size() == 9u) {
2528  // Onscreen render target.
2529  EXPECT_EQ(test_allocator->GetDescriptors()[0].size, ISize(1000, 1000));
2530  EXPECT_EQ(test_allocator->GetDescriptors()[1].size, ISize(1000, 1000));
2531  EXPECT_EQ(test_allocator->GetDescriptors()[2].size, ISize(1000, 1000));
2532  EXPECT_EQ(test_allocator->GetDescriptors()[3].size, ISize(1000, 1000));
2533  EXPECT_EQ(test_allocator->GetDescriptors()[4].size, ISize(1000, 1000));
2534 
2535  EXPECT_EQ(test_allocator->GetDescriptors()[5].size, ISize(200, 200));
2536  EXPECT_EQ(test_allocator->GetDescriptors()[5].size, ISize(200, 200));
2537  EXPECT_EQ(test_allocator->GetDescriptors()[6].size, ISize(200, 200));
2538  EXPECT_EQ(test_allocator->GetDescriptors()[7].size, ISize(200, 200));
2539  } else {
2540  EXPECT_TRUE(false);
2541  }
2542 }

References impeller::Color::BlackTransparent(), impeller::RenderTarget::CreateOffscreen(), impeller::Entity::GetCoverage(), impeller::kClear, impeller::kColorBurn, impeller::RenderTarget::kDefaultColorAttachmentConfig, impeller::kDevicePrivate, impeller::kDontCare, impeller::TypographerContextSkia::Make(), impeller::Geometry::MakeRect(), impeller::Matrix::MakeScale(), impeller::TSize< int64_t >::MakeWH(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Color::Red(), impeller::Entity::SetBlendMode(), impeller::Entity::SetContents(), impeller::Entity::SetTransform(), and impeller::RenderTarget::AttachmentConfig::storage_mode.

◆ TEST_P() [266/384]

impeller::testing::TEST_P ( EntityTest  ,
AtlasContentsSubAtlas   
)

Definition at line 1970 of file entity_unittests.cc.

1970  {
1971  auto boston = CreateTextureForFixture("boston.jpg");
1972 
1973  {
1974  auto contents = std::make_shared<AtlasContents>();
1975  contents->SetBlendMode(BlendMode::kSourceOver);
1976  contents->SetTexture(boston);
1977  contents->SetColors({
1978  Color::Red(),
1979  Color::Red(),
1980  Color::Red(),
1981  });
1982  contents->SetTextureCoordinates({
1983  Rect::MakeLTRB(0, 0, 10, 10),
1984  Rect::MakeLTRB(0, 0, 10, 10),
1985  Rect::MakeLTRB(0, 0, 10, 10),
1986  });
1987  contents->SetTransforms({
1988  Matrix::MakeTranslation(Vector2(0, 0)),
1989  Matrix::MakeTranslation(Vector2(100, 100)),
1990  Matrix::MakeTranslation(Vector2(200, 200)),
1991  });
1992 
1993  // Since all colors and sample rects are the same, there should
1994  // only be a single entry in the sub atlas.
1995  auto subatlas = contents->GenerateSubAtlas();
1996  ASSERT_EQ(subatlas->sub_texture_coords.size(), 1u);
1997  }
1998 
1999  {
2000  auto contents = std::make_shared<AtlasContents>();
2001  contents->SetBlendMode(BlendMode::kSourceOver);
2002  contents->SetTexture(boston);
2003  contents->SetColors({
2004  Color::Red(),
2005  Color::Green(),
2006  Color::Blue(),
2007  });
2008  contents->SetTextureCoordinates({
2009  Rect::MakeLTRB(0, 0, 10, 10),
2010  Rect::MakeLTRB(0, 0, 10, 10),
2011  Rect::MakeLTRB(0, 0, 10, 10),
2012  });
2013  contents->SetTransforms({
2014  Matrix::MakeTranslation(Vector2(0, 0)),
2015  Matrix::MakeTranslation(Vector2(100, 100)),
2016  Matrix::MakeTranslation(Vector2(200, 200)),
2017  });
2018 
2019  // Since all colors are different, there are three entires.
2020  auto subatlas = contents->GenerateSubAtlas();
2021  ASSERT_EQ(subatlas->sub_texture_coords.size(), 3u);
2022 
2023  // The translations are kept but the sample rects point into
2024  // different parts of the sub atlas.
2025  ASSERT_EQ(subatlas->result_texture_coords[0], Rect::MakeXYWH(0, 0, 10, 10));
2026  ASSERT_EQ(subatlas->result_texture_coords[1],
2027  Rect::MakeXYWH(11, 0, 10, 10));
2028  ASSERT_EQ(subatlas->result_texture_coords[2],
2029  Rect::MakeXYWH(22, 0, 10, 10));
2030  }
2031 }

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() [267/384]

impeller::testing::TEST_P ( EntityTest  ,
BezierCircleScaled   
)

Definition at line 926 of file entity_unittests.cc.

926  {
927  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
928  static float scale = 20;
929 
930  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
931  ImGui::SliderFloat("Scale", &scale, 1, 100);
932  ImGui::End();
933 
934  Entity entity;
935  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
936  auto path = PathBuilder{}
937  .MoveTo({97.325, 34.818})
938  .CubicCurveTo({98.50862885295136, 34.81812293973836},
939  {99.46822048142015, 33.85863261475589},
940  {99.46822048142015, 32.67499810206613})
941  .CubicCurveTo({99.46822048142015, 31.491363589376355},
942  {98.50862885295136, 30.53187326439389},
943  {97.32499434685802, 30.531998226542708})
944  .CubicCurveTo({96.14153655073771, 30.532123170035373},
945  {95.18222070648729, 31.491540299350355},
946  {95.18222070648729, 32.67499810206613})
947  .CubicCurveTo({95.18222070648729, 33.85845590478189},
948  {96.14153655073771, 34.81787303409686},
949  {97.32499434685802, 34.81799797758954})
950  .Close()
951  .TakePath();
952  entity.SetTransform(
953  Matrix::MakeScale({scale, scale, 1.0}).Translate({-90, -20, 0}));
954  entity.SetContents(SolidColorContents::Make(std::move(path), Color::Red()));
955  return entity.Render(context, pass);
956  };
957  ASSERT_TRUE(OpenPlaygroundHere(callback));
958 }

References impeller::Close(), impeller::SolidColorContents::Make(), impeller::Matrix::MakeScale(), impeller::PathBuilder::MoveTo(), impeller::Color::Red(), impeller::Entity::Render(), impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [268/384]

impeller::testing::TEST_P ( EntityTest  ,
BlendingModeOptions   
)

Definition at line 799 of file entity_unittests.cc.

799  {
800  std::vector<const char*> blend_mode_names;
801  std::vector<BlendMode> blend_mode_values;
802  {
803  // Force an exhausiveness check with a switch. When adding blend modes,
804  // update this switch with a new name/value to make it selectable in the
805  // test GUI.
806 
807  const BlendMode b{};
808  static_assert(b == BlendMode::kClear); // Ensure the first item in
809  // the switch is the first
810  // item in the enum.
811  static_assert(Entity::kLastPipelineBlendMode == BlendMode::kModulate);
812  switch (b) {
813  case BlendMode::kClear:
814  blend_mode_names.push_back("Clear");
815  blend_mode_values.push_back(BlendMode::kClear);
816  case BlendMode::kSource:
817  blend_mode_names.push_back("Source");
818  blend_mode_values.push_back(BlendMode::kSource);
819  case BlendMode::kDestination:
820  blend_mode_names.push_back("Destination");
821  blend_mode_values.push_back(BlendMode::kDestination);
822  case BlendMode::kSourceOver:
823  blend_mode_names.push_back("SourceOver");
824  blend_mode_values.push_back(BlendMode::kSourceOver);
825  case BlendMode::kDestinationOver:
826  blend_mode_names.push_back("DestinationOver");
827  blend_mode_values.push_back(BlendMode::kDestinationOver);
828  case BlendMode::kSourceIn:
829  blend_mode_names.push_back("SourceIn");
830  blend_mode_values.push_back(BlendMode::kSourceIn);
831  case BlendMode::kDestinationIn:
832  blend_mode_names.push_back("DestinationIn");
833  blend_mode_values.push_back(BlendMode::kDestinationIn);
834  case BlendMode::kSourceOut:
835  blend_mode_names.push_back("SourceOut");
836  blend_mode_values.push_back(BlendMode::kSourceOut);
837  case BlendMode::kDestinationOut:
838  blend_mode_names.push_back("DestinationOut");
839  blend_mode_values.push_back(BlendMode::kDestinationOut);
840  case BlendMode::kSourceATop:
841  blend_mode_names.push_back("SourceATop");
842  blend_mode_values.push_back(BlendMode::kSourceATop);
843  case BlendMode::kDestinationATop:
844  blend_mode_names.push_back("DestinationATop");
845  blend_mode_values.push_back(BlendMode::kDestinationATop);
846  case BlendMode::kXor:
847  blend_mode_names.push_back("Xor");
848  blend_mode_values.push_back(BlendMode::kXor);
849  case BlendMode::kPlus:
850  blend_mode_names.push_back("Plus");
851  blend_mode_values.push_back(BlendMode::kPlus);
852  case BlendMode::kModulate:
853  blend_mode_names.push_back("Modulate");
854  blend_mode_values.push_back(BlendMode::kModulate);
855  };
856  }
857 
858  auto callback = [&](ContentContext& context, RenderPass& pass) {
859  auto world_matrix = Matrix::MakeScale(GetContentScale());
860  auto draw_rect = [&context, &pass, &world_matrix](
861  Rect rect, Color color, BlendMode blend_mode) -> bool {
862  using VS = SolidFillPipeline::VertexShader;
863 
864  VertexBufferBuilder<VS::PerVertexData> vtx_builder;
865  {
866  auto r = rect.GetLTRB();
867  vtx_builder.AddVertices({
868  {Point(r[0], r[1])},
869  {Point(r[2], r[1])},
870  {Point(r[2], r[3])},
871  {Point(r[0], r[1])},
872  {Point(r[2], r[3])},
873  {Point(r[0], r[3])},
874  });
875  }
876 
877  Command cmd;
878  DEBUG_COMMAND_INFO(cmd, "Blended Rectangle");
879  auto options = OptionsFromPass(pass);
880  options.blend_mode = blend_mode;
881  options.primitive_type = PrimitiveType::kTriangle;
882  cmd.pipeline = context.GetSolidFillPipeline(options);
883  cmd.BindVertices(
884  vtx_builder.CreateVertexBuffer(pass.GetTransientsBuffer()));
885 
886  VS::FrameInfo frame_info;
887  frame_info.mvp = pass.GetOrthographicTransform() * world_matrix;
888  frame_info.color = color.Premultiply();
889  VS::BindFrameInfo(cmd,
890  pass.GetTransientsBuffer().EmplaceUniform(frame_info));
891 
892  return pass.AddCommand(std::move(cmd));
893  };
894 
895  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
896  static Color color1(1, 0, 0, 0.5), color2(0, 1, 0, 0.5);
897  ImGui::ColorEdit4("Color 1", reinterpret_cast<float*>(&color1));
898  ImGui::ColorEdit4("Color 2", reinterpret_cast<float*>(&color2));
899  static int current_blend_index = 3;
900  ImGui::ListBox("Blending mode", &current_blend_index,
901  blend_mode_names.data(), blend_mode_names.size());
902  ImGui::End();
903 
904  BlendMode selected_mode = blend_mode_values[current_blend_index];
905 
906  Point a, b, c, d;
907  std::tie(a, b) = IMPELLER_PLAYGROUND_LINE(
908  Point(400, 100), Point(200, 300), 20, Color::White(), Color::White());
909  std::tie(c, d) = IMPELLER_PLAYGROUND_LINE(
910  Point(470, 190), Point(270, 390), 20, Color::White(), Color::White());
911 
912  bool result = true;
913  result = result &&
914  draw_rect(Rect::MakeXYWH(0, 0, pass.GetRenderTargetSize().width,
915  pass.GetRenderTargetSize().height),
916  Color(), BlendMode::kClear);
917  result = result && draw_rect(Rect::MakeLTRB(a.x, a.y, b.x, b.y), color1,
918  BlendMode::kSourceOver);
919  result = result && draw_rect(Rect::MakeLTRB(c.x, c.y, d.x, d.y), color2,
920  selected_mode);
921  return result;
922  };
923  ASSERT_TRUE(OpenPlaygroundHere(callback));
924 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::Command::BindVertices(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), DEBUG_COMMAND_INFO, impeller::ContentContext::GetSolidFillPipeline(), IMPELLER_PLAYGROUND_LINE, impeller::kClear, impeller::kDestination, impeller::kDestinationATop, impeller::kDestinationIn, impeller::kDestinationOut, impeller::kDestinationOver, impeller::Entity::kLastPipelineBlendMode, impeller::kModulate, impeller::kPlus, impeller::kSource, impeller::kSourceATop, impeller::kSourceIn, impeller::kSourceOut, impeller::kSourceOver, impeller::kTriangle, impeller::kXor, impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeScale(), impeller::TRect< Scalar >::MakeXYWH(), impeller::OptionsFromPass(), impeller::Command::pipeline, impeller::Color::White(), impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ TEST_P() [269/384]

impeller::testing::TEST_P ( EntityTest  ,
BorderMaskBlurCoverageIsCorrect   
)

Definition at line 1333 of file entity_unittests.cc.

1333  {
1334  auto fill = std::make_shared<SolidColorContents>();
1335  fill->SetGeometry(Geometry::MakeFillPath(
1336  PathBuilder{}.AddRect(Rect::MakeXYWH(0, 0, 300, 400)).TakePath()));
1337  fill->SetColor(Color::CornflowerBlue());
1338  auto border_mask_blur = FilterContents::MakeBorderMaskBlur(
1339  FilterInput::Make(fill), Radius{3}, Radius{4});
1340 
1341  {
1342  Entity e;
1343  e.SetTransform(Matrix());
1344  auto actual = border_mask_blur->GetCoverage(e);
1345  auto expected = Rect::MakeXYWH(-3, -4, 306, 408);
1346  ASSERT_TRUE(actual.has_value());
1347  ASSERT_RECT_NEAR(actual.value(), expected);
1348  }
1349 
1350  {
1351  Entity e;
1352  e.SetTransform(Matrix::MakeRotationZ(Radians{kPi / 4}));
1353  auto actual = border_mask_blur->GetCoverage(e);
1354  auto expected = Rect::MakeXYWH(-287.792, -4.94975, 504.874, 504.874);
1355  ASSERT_TRUE(actual.has_value());
1356  ASSERT_RECT_NEAR(actual.value(), expected);
1357  }
1358 }

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() [270/384]

impeller::testing::TEST_P ( EntityTest  ,
CanCreateEntity   
)

Definition at line 66 of file entity_unittests.cc.

66  {
67  Entity entity;
68  ASSERT_TRUE(entity.GetTransform().IsIdentity());
69 }

References impeller::Entity::GetTransform(), and impeller::Matrix::IsIdentity().

◆ TEST_P() [271/384]

impeller::testing::TEST_P ( EntityTest  ,
CanDrawCorrectlyWithRotatedTransform   
)

Definition at line 483 of file entity_unittests.cc.

483  {
484  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
485  const char* input_axis[] = {"X", "Y", "Z"};
486  static int rotation_axis_index = 0;
487  static float rotation = 0;
488  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
489  ImGui::SliderFloat("Rotation", &rotation, -kPi, kPi);
490  ImGui::Combo("Rotation Axis", &rotation_axis_index, input_axis,
491  sizeof(input_axis) / sizeof(char*));
492  Matrix rotation_matrix;
493  switch (rotation_axis_index) {
494  case 0:
495  rotation_matrix = Matrix::MakeRotationX(Radians(rotation));
496  break;
497  case 1:
498  rotation_matrix = Matrix::MakeRotationY(Radians(rotation));
499  break;
500  case 2:
501  rotation_matrix = Matrix::MakeRotationZ(Radians(rotation));
502  break;
503  default:
504  rotation_matrix = Matrix{};
505  break;
506  }
507 
508  if (ImGui::Button("Reset")) {
509  rotation = 0;
510  }
511  ImGui::End();
512  Matrix current_transform =
513  Matrix::MakeScale(GetContentScale())
514  .MakeTranslation(
515  Vector3(Point(pass.GetRenderTargetSize().width / 2.0,
516  pass.GetRenderTargetSize().height / 2.0)));
517  Matrix result_transform = current_transform * rotation_matrix;
518  Path path =
519  PathBuilder{}.AddRect(Rect::MakeXYWH(-300, -400, 600, 800)).TakePath();
520 
521  Entity entity;
522  entity.SetTransform(result_transform);
523  entity.SetContents(SolidColorContents::Make(std::move(path), Color::Red()));
524  return entity.Render(context, pass);
525  };
526  ASSERT_TRUE(OpenPlaygroundHere(callback));
527 }

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() [272/384]

impeller::testing::TEST_P ( EntityTest  ,
CanDrawRect   
)

Definition at line 221 of file entity_unittests.cc.

221  {
222  auto contents = std::make_shared<SolidColorContents>();
223  contents->SetGeometry(Geometry::MakeRect(Rect::MakeXYWH(100, 100, 100, 100)));
224  contents->SetColor(Color::Red());
225 
226  Entity entity;
227  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
228  entity.SetContents(contents);
229 
230  ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
231 }

References impeller::Geometry::MakeRect(), impeller::Matrix::MakeScale(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Color::Red(), impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [273/384]

impeller::testing::TEST_P ( EntityTest  ,
CanDrawRRect   
)

Definition at line 233 of file entity_unittests.cc.

233  {
234  auto contents = std::make_shared<SolidColorContents>();
235  auto path = PathBuilder{}
236  .SetConvexity(Convexity::kConvex)
237  .AddRoundedRect(Rect::MakeXYWH(100, 100, 100, 100), 10.0)
238  .TakePath();
239  contents->SetGeometry(Geometry::MakeFillPath(std::move(path)));
240  contents->SetColor(Color::Red());
241 
242  Entity entity;
243  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
244  entity.SetContents(contents);
245 
246  ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
247 }

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() [274/384]

impeller::testing::TEST_P ( EntityTest  ,
ClipContentsGetClipCoverageIsCorrect   
)

Definition at line 1669 of file entity_unittests.cc.

1669  {
1670  // Intersection: No stencil coverage, no geometry.
1671  {
1672  auto clip = std::make_shared<ClipContents>();
1673  clip->SetClipOperation(Entity::ClipOperation::kIntersect);
1674  auto result = clip->GetClipCoverage(Entity{}, Rect{});
1675 
1676  ASSERT_FALSE(result.coverage.has_value());
1677  }
1678 
1679  // Intersection: No stencil coverage, with geometry.
1680  {
1681  auto clip = std::make_shared<ClipContents>();
1682  clip->SetClipOperation(Entity::ClipOperation::kIntersect);
1683  clip->SetGeometry(Geometry::MakeFillPath(
1684  PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 100, 100)).TakePath()));
1685  auto result = clip->GetClipCoverage(Entity{}, Rect{});
1686 
1687  ASSERT_FALSE(result.coverage.has_value());
1688  }
1689 
1690  // Intersection: With stencil coverage, no geometry.
1691  {
1692  auto clip = std::make_shared<ClipContents>();
1693  clip->SetClipOperation(Entity::ClipOperation::kIntersect);
1694  auto result =
1695  clip->GetClipCoverage(Entity{}, Rect::MakeLTRB(0, 0, 100, 100));
1696 
1697  ASSERT_FALSE(result.coverage.has_value());
1698  }
1699 
1700  // Intersection: With stencil coverage, with geometry.
1701  {
1702  auto clip = std::make_shared<ClipContents>();
1703  clip->SetClipOperation(Entity::ClipOperation::kIntersect);
1704  clip->SetGeometry(Geometry::MakeFillPath(
1705  PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 50, 50)).TakePath()));
1706  auto result =
1707  clip->GetClipCoverage(Entity{}, Rect::MakeLTRB(0, 0, 100, 100));
1708 
1709  ASSERT_TRUE(result.coverage.has_value());
1710  ASSERT_RECT_NEAR(result.coverage.value(), Rect::MakeLTRB(0, 0, 50, 50));
1711  ASSERT_EQ(result.type, Contents::ClipCoverage::Type::kAppend);
1712  }
1713 
1714  // Difference: With stencil coverage, with geometry.
1715  {
1716  auto clip = std::make_shared<ClipContents>();
1717  clip->SetClipOperation(Entity::ClipOperation::kDifference);
1718  clip->SetGeometry(Geometry::MakeFillPath(
1719  PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 50, 50)).TakePath()));
1720  auto result =
1721  clip->GetClipCoverage(Entity{}, Rect::MakeLTRB(0, 0, 100, 100));
1722 
1723  ASSERT_TRUE(result.coverage.has_value());
1724  ASSERT_RECT_NEAR(result.coverage.value(), Rect::MakeLTRB(0, 0, 100, 100));
1725  ASSERT_EQ(result.type, Contents::ClipCoverage::Type::kAppend);
1726  }
1727 }

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() [275/384]

impeller::testing::TEST_P ( EntityTest  ,
ClipContentsShouldRenderIsCorrect   
)

Definition at line 1645 of file entity_unittests.cc.

1645  {
1646  // For clip ops, `ShouldRender` should always return true.
1647 
1648  // Clip.
1649  {
1650  auto clip = std::make_shared<ClipContents>();
1651  ASSERT_TRUE(clip->ShouldRender(Entity{}, Rect::MakeSize(Size{100, 100})));
1652  clip->SetGeometry(Geometry::MakeFillPath(
1653  PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 100, 100)).TakePath()));
1654  ASSERT_TRUE(clip->ShouldRender(Entity{}, Rect::MakeSize(Size{100, 100})));
1655  ASSERT_TRUE(
1656  clip->ShouldRender(Entity{}, Rect::MakeLTRB(-100, -100, -50, -50)));
1657  }
1658 
1659  // Clip restore.
1660  {
1661  auto restore = std::make_shared<ClipRestoreContents>();
1662  ASSERT_TRUE(
1663  restore->ShouldRender(Entity{}, Rect::MakeSize(Size{100, 100})));
1664  ASSERT_TRUE(
1665  restore->ShouldRender(Entity{}, Rect::MakeLTRB(-100, -100, -50, -50)));
1666  }
1667 }

References impeller::PathBuilder::AddRect(), impeller::Geometry::MakeFillPath(), impeller::TRect< Scalar >::MakeLTRB(), and impeller::TRect< Scalar >::MakeSize().

◆ TEST_P() [276/384]

impeller::testing::TEST_P ( EntityTest  ,
ColorFilterContentsWithLargeGeometry   
)

Definition at line 2434 of file entity_unittests.cc.

2434  {
2435  Entity entity;
2436  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
2437  auto src_contents = std::make_shared<SolidColorContents>();
2438  src_contents->SetGeometry(
2439  Geometry::MakeRect(Rect::MakeLTRB(-300, -500, 30000, 50000)));
2440  src_contents->SetColor(Color::Red());
2441 
2442  auto dst_contents = std::make_shared<SolidColorContents>();
2443  dst_contents->SetGeometry(
2444  Geometry::MakeRect(Rect::MakeLTRB(300, 500, 20000, 30000)));
2445  dst_contents->SetColor(Color::Blue());
2446 
2447  auto contents = ColorFilterContents::MakeBlend(
2448  BlendMode::kSourceOver, {FilterInput::Make(dst_contents, false),
2449  FilterInput::Make(src_contents, false)});
2450  entity.SetContents(std::move(contents));
2451  ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
2452 }

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() [277/384]

impeller::testing::TEST_P ( EntityTest  ,
ColorFilterWithForegroundColorAdvancedBlend   
)

Definition at line 2248 of file entity_unittests.cc.

2248  {
2249  auto image = CreateTextureForFixture("boston.jpg");
2250  auto filter = ColorFilterContents::MakeBlend(
2251  BlendMode::kColorBurn, FilterInput::Make({image}), Color::Red());
2252 
2253  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
2254  Entity entity;
2255  entity.SetTransform(Matrix::MakeScale(GetContentScale()) *
2256  Matrix::MakeTranslation({500, 300}) *
2257  Matrix::MakeScale(Vector2{0.5, 0.5}));
2258  entity.SetContents(filter);
2259  return entity.Render(context, pass);
2260  };
2261  ASSERT_TRUE(OpenPlaygroundHere(callback));
2262 }

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() [278/384]

impeller::testing::TEST_P ( EntityTest  ,
ColorFilterWithForegroundColorClearBlend   
)

Definition at line 2264 of file entity_unittests.cc.

2264  {
2265  auto image = CreateTextureForFixture("boston.jpg");
2266  auto filter = ColorFilterContents::MakeBlend(
2267  BlendMode::kClear, FilterInput::Make({image}), Color::Red());
2268 
2269  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
2270  Entity entity;
2271  entity.SetTransform(Matrix::MakeScale(GetContentScale()) *
2272  Matrix::MakeTranslation({500, 300}) *
2273  Matrix::MakeScale(Vector2{0.5, 0.5}));
2274  entity.SetContents(filter);
2275  return entity.Render(context, pass);
2276  };
2277  ASSERT_TRUE(OpenPlaygroundHere(callback));
2278 }

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() [279/384]

impeller::testing::TEST_P ( EntityTest  ,
ColorFilterWithForegroundColorDstBlend   
)

Definition at line 2296 of file entity_unittests.cc.

2296  {
2297  auto image = CreateTextureForFixture("boston.jpg");
2298  auto filter = ColorFilterContents::MakeBlend(
2299  BlendMode::kDestination, FilterInput::Make({image}), Color::Red());
2300 
2301  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
2302  Entity entity;
2303  entity.SetTransform(Matrix::MakeScale(GetContentScale()) *
2304  Matrix::MakeTranslation({500, 300}) *
2305  Matrix::MakeScale(Vector2{0.5, 0.5}));
2306  entity.SetContents(filter);
2307  return entity.Render(context, pass);
2308  };
2309  ASSERT_TRUE(OpenPlaygroundHere(callback));
2310 }

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() [280/384]

impeller::testing::TEST_P ( EntityTest  ,
ColorFilterWithForegroundColorSrcBlend   
)

Definition at line 2280 of file entity_unittests.cc.

2280  {
2281  auto image = CreateTextureForFixture("boston.jpg");
2282  auto filter = ColorFilterContents::MakeBlend(
2283  BlendMode::kSource, FilterInput::Make({image}), Color::Red());
2284 
2285  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
2286  Entity entity;
2287  entity.SetTransform(Matrix::MakeScale(GetContentScale()) *
2288  Matrix::MakeTranslation({500, 300}) *
2289  Matrix::MakeScale(Vector2{0.5, 0.5}));
2290  entity.SetContents(filter);
2291  return entity.Render(context, pass);
2292  };
2293  ASSERT_TRUE(OpenPlaygroundHere(callback));
2294 }

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() [281/384]

impeller::testing::TEST_P ( EntityTest  ,
ColorFilterWithForegroundColorSrcInBlend   
)

Definition at line 2312 of file entity_unittests.cc.

2312  {
2313  auto image = CreateTextureForFixture("boston.jpg");
2314  auto filter = ColorFilterContents::MakeBlend(
2315  BlendMode::kSourceIn, FilterInput::Make({image}), Color::Red());
2316 
2317  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
2318  Entity entity;
2319  entity.SetTransform(Matrix::MakeScale(GetContentScale()) *
2320  Matrix::MakeTranslation({500, 300}) *
2321  Matrix::MakeScale(Vector2{0.5, 0.5}));
2322  entity.SetContents(filter);
2323  return entity.Render(context, pass);
2324  };
2325  ASSERT_TRUE(OpenPlaygroundHere(callback));
2326 }

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() [282/384]

impeller::testing::TEST_P ( EntityTest  ,
ColorMatrixFilterCoverageIsCorrect   
)

Definition at line 1779 of file entity_unittests.cc.

1779  {
1780  // Set up a simple color background.
1781  auto fill = std::make_shared<SolidColorContents>();
1782  fill->SetGeometry(Geometry::MakeFillPath(
1783  PathBuilder{}.AddRect(Rect::MakeXYWH(0, 0, 300, 400)).TakePath()));
1784  fill->SetColor(Color::Coral());
1785 
1786  // Set the color matrix filter.
1787  ColorMatrix matrix = {
1788  1, 1, 1, 1, 1, //
1789  1, 1, 1, 1, 1, //
1790  1, 1, 1, 1, 1, //
1791  1, 1, 1, 1, 1, //
1792  };
1793 
1794  auto filter =
1795  ColorFilterContents::MakeColorMatrix(FilterInput::Make(fill), matrix);
1796 
1797  Entity e;
1798  e.SetTransform(Matrix());
1799 
1800  // Confirm that the actual filter coverage matches the expected coverage.
1801  auto actual = filter->GetCoverage(e);
1802  auto expected = Rect::MakeXYWH(0, 0, 300, 400);
1803 
1804  ASSERT_TRUE(actual.has_value());
1805  ASSERT_RECT_NEAR(actual.value(), expected);
1806 }

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() [283/384]

impeller::testing::TEST_P ( EntityTest  ,
ColorMatrixFilterEditable   
)

Definition at line 1808 of file entity_unittests.cc.

1808  {
1809  auto bay_bridge = CreateTextureForFixture("bay_bridge.jpg");
1810  ASSERT_TRUE(bay_bridge);
1811 
1812  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1813  // UI state.
1814  static ColorMatrix color_matrix = {
1815  1, 0, 0, 0, 0, //
1816  0, 3, 0, 0, 0, //
1817  0, 0, 1, 0, 0, //
1818  0, 0, 0, 1, 0, //
1819  };
1820  static float offset[2] = {500, 400};
1821  static float rotation = 0;
1822  static float scale[2] = {0.65, 0.65};
1823  static float skew[2] = {0, 0};
1824 
1825  // Define the ImGui
1826  ImGui::Begin("Color Matrix", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1827  {
1828  std::string label = "##1";
1829  for (int i = 0; i < 20; i += 5) {
1830  ImGui::InputScalarN(label.c_str(), ImGuiDataType_Float,
1831  &(color_matrix.array[i]), 5, nullptr, nullptr,
1832  "%.2f", 0);
1833  label[2]++;
1834  }
1835 
1836  ImGui::SliderFloat2("Translation", &offset[0], 0,
1837  pass.GetRenderTargetSize().width);
1838  ImGui::SliderFloat("Rotation", &rotation, 0, kPi * 2);
1839  ImGui::SliderFloat2("Scale", &scale[0], 0, 3);
1840  ImGui::SliderFloat2("Skew", &skew[0], -3, 3);
1841  }
1842  ImGui::End();
1843 
1844  // Set the color matrix filter.
1845  auto filter = ColorFilterContents::MakeColorMatrix(
1846  FilterInput::Make(bay_bridge), color_matrix);
1847 
1848  // Define the entity with the color matrix filter.
1849  Entity entity;
1850  entity.SetTransform(
1851  Matrix::MakeScale(GetContentScale()) *
1852  Matrix::MakeTranslation(Vector3(offset[0], offset[1])) *
1853  Matrix::MakeRotationZ(Radians(rotation)) *
1854  Matrix::MakeScale(Vector2(scale[0], scale[1])) *
1855  Matrix::MakeSkew(skew[0], skew[1]) *
1856  Matrix::MakeTranslation(-Point(bay_bridge->GetSize()) / 2));
1857  entity.SetContents(filter);
1858  entity.Render(context, pass);
1859 
1860  return true;
1861  };
1862 
1863  ASSERT_TRUE(OpenPlaygroundHere(callback));
1864 }

References impeller::ColorMatrix::array, impeller::kPi, impeller::FilterInput::Make(), impeller::ColorFilterContents::MakeColorMatrix(), impeller::Matrix::MakeRotationZ(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeSkew(), impeller::Matrix::MakeTranslation(), impeller::Entity::Render(), impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [284/384]

impeller::testing::TEST_P ( EntityTest  ,
ConicalGradientContentsIsOpaque   
)

Definition at line 2352 of file entity_unittests.cc.

2352  {
2353  ConicalGradientContents contents;
2354  contents.SetColors({Color::CornflowerBlue()});
2355  ASSERT_FALSE(contents.IsOpaque());
2356  contents.SetColors({Color::CornflowerBlue().WithAlpha(0.5)});
2357  ASSERT_FALSE(contents.IsOpaque());
2358 }

References impeller::Color::CornflowerBlue(), impeller::Contents::IsOpaque(), impeller::ConicalGradientContents::SetColors(), and impeller::Color::WithAlpha().

◆ TEST_P() [285/384]

impeller::testing::TEST_P ( EntityTest  ,
ContentContextOptionsHasReasonableHashFunctions   
)

Definition at line 2613 of file entity_unittests.cc.

2613  {
2614  ContentContextOptions opts;
2615  auto hash_a = ContentContextOptions::Hash{}(opts);
2616 
2617  opts.blend_mode = BlendMode::kColorBurn;
2618  auto hash_b = ContentContextOptions::Hash{}(opts);
2619 
2620  opts.has_stencil_attachment = false;
2621  auto hash_c = ContentContextOptions::Hash{}(opts);
2622 
2623  opts.primitive_type = PrimitiveType::kPoint;
2624  auto hash_d = ContentContextOptions::Hash{}(opts);
2625 
2626  EXPECT_NE(hash_a, hash_b);
2627  EXPECT_NE(hash_b, hash_c);
2628  EXPECT_NE(hash_c, hash_d);
2629 }

References impeller::ContentContextOptions::blend_mode, impeller::ContentContextOptions::has_stencil_attachment, impeller::kColorBurn, impeller::kPoint, and impeller::ContentContextOptions::primitive_type.

◆ TEST_P() [286/384]

impeller::testing::TEST_P ( EntityTest  ,
ContentsGetBoundsForEmptyPathReturnsNullopt   
)

Definition at line 1274 of file entity_unittests.cc.

1274  {
1275  Entity entity;
1276  entity.SetContents(std::make_shared<SolidColorContents>());
1277  ASSERT_FALSE(entity.GetCoverage().has_value());
1278 }

References impeller::Entity::GetCoverage(), and impeller::Entity::SetContents().

◆ TEST_P() [287/384]

impeller::testing::TEST_P ( EntityTest  ,
CoverageForStrokePathWithNegativeValuesInTransform   
)

Definition at line 2328 of file entity_unittests.cc.

2328  {
2329  auto arrow_head = PathBuilder{}
2330  .MoveTo({50, 120})
2331  .LineTo({120, 190})
2332  .LineTo({190, 120})
2333  .TakePath();
2334  auto geometry = Geometry::MakeStrokePath(std::move(arrow_head), 15.0, 4.0,
2335  Cap::kRound, Join::kRound);
2336 
2337  auto transform = Matrix::MakeTranslation({300, 300}) *
2338  Matrix::MakeRotationZ(Radians(kPiOver2));
2339  EXPECT_LT(transform.e[0][0], 0.f);
2340  auto coverage = geometry->GetCoverage(transform);
2341  ASSERT_RECT_NEAR(coverage.value(), Rect::MakeXYWH(102.5, 342.5, 85, 155));
2342 }

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() [288/384]

impeller::testing::TEST_P ( EntityTest  ,
CubicCurveAndOverlapTest   
)

Definition at line 529 of file entity_unittests.cc.

529  {
530  // Compare with https://fiddle.skia.org/c/7a05a3e186c65a8dfb732f68020aae06
531  Path path =
532  PathBuilder{}
533  .MoveTo({359.934, 96.6335})
534  .CubicCurveTo({358.189, 96.7055}, {356.436, 96.7908},
535  {354.673, 96.8895})
536  .CubicCurveTo({354.571, 96.8953}, {354.469, 96.9016},
537  {354.367, 96.9075})
538  .CubicCurveTo({352.672, 97.0038}, {350.969, 97.113},
539  {349.259, 97.2355})
540  .CubicCurveTo({349.048, 97.2506}, {348.836, 97.2678},
541  {348.625, 97.2834})
542  .CubicCurveTo({347.019, 97.4014}, {345.407, 97.5299},
543  {343.789, 97.6722})
544  .CubicCurveTo({343.428, 97.704}, {343.065, 97.7402},
545  {342.703, 97.7734})
546  .CubicCurveTo({341.221, 97.9086}, {339.736, 98.0505},
547  {338.246, 98.207})
548  .CubicCurveTo({337.702, 98.2642}, {337.156, 98.3292},
549  {336.612, 98.3894})
550  .CubicCurveTo({335.284, 98.5356}, {333.956, 98.6837},
551  {332.623, 98.8476})
552  .CubicCurveTo({332.495, 98.8635}, {332.366, 98.8818},
553  {332.237, 98.8982})
554  .LineTo({332.237, 102.601})
555  .LineTo({321.778, 102.601})
556  .LineTo({321.778, 100.382})
557  .CubicCurveTo({321.572, 100.413}, {321.367, 100.442},
558  {321.161, 100.476})
559  .CubicCurveTo({319.22, 100.79}, {317.277, 101.123},
560  {315.332, 101.479})
561  .CubicCurveTo({315.322, 101.481}, {315.311, 101.482},
562  {315.301, 101.484})
563  .LineTo({310.017, 105.94})
564  .LineTo({309.779, 105.427})
565  .LineTo({314.403, 101.651})
566  .CubicCurveTo({314.391, 101.653}, {314.379, 101.656},
567  {314.368, 101.658})
568  .CubicCurveTo({312.528, 102.001}, {310.687, 102.366},
569  {308.846, 102.748})
570  .CubicCurveTo({307.85, 102.955}, {306.855, 103.182}, {305.859, 103.4})
571  .CubicCurveTo({305.048, 103.579}, {304.236, 103.75},
572  {303.425, 103.936})
573  .LineTo({299.105, 107.578})
574  .LineTo({298.867, 107.065})
575  .LineTo({302.394, 104.185})
576  .LineTo({302.412, 104.171})
577  .CubicCurveTo({301.388, 104.409}, {300.366, 104.67},
578  {299.344, 104.921})
579  .CubicCurveTo({298.618, 105.1}, {297.89, 105.269}, {297.165, 105.455})
580  .CubicCurveTo({295.262, 105.94}, {293.36, 106.445},
581  {291.462, 106.979})
582  .CubicCurveTo({291.132, 107.072}, {290.802, 107.163},
583  {290.471, 107.257})
584  .CubicCurveTo({289.463, 107.544}, {288.455, 107.839},
585  {287.449, 108.139})
586  .CubicCurveTo({286.476, 108.431}, {285.506, 108.73},
587  {284.536, 109.035})
588  .CubicCurveTo({283.674, 109.304}, {282.812, 109.579},
589  {281.952, 109.859})
590  .CubicCurveTo({281.177, 110.112}, {280.406, 110.377},
591  {279.633, 110.638})
592  .CubicCurveTo({278.458, 111.037}, {277.256, 111.449},
593  {276.803, 111.607})
594  .CubicCurveTo({276.76, 111.622}, {276.716, 111.637},
595  {276.672, 111.653})
596  .CubicCurveTo({275.017, 112.239}, {273.365, 112.836},
597  {271.721, 113.463})
598  .LineTo({271.717, 113.449})
599  .CubicCurveTo({271.496, 113.496}, {271.238, 113.559},
600  {270.963, 113.628})
601  .CubicCurveTo({270.893, 113.645}, {270.822, 113.663},
602  {270.748, 113.682})
603  .CubicCurveTo({270.468, 113.755}, {270.169, 113.834},
604  {269.839, 113.926})
605  .CubicCurveTo({269.789, 113.94}, {269.732, 113.957},
606  {269.681, 113.972})
607  .CubicCurveTo({269.391, 114.053}, {269.081, 114.143},
608  {268.756, 114.239})
609  .CubicCurveTo({268.628, 114.276}, {268.5, 114.314},
610  {268.367, 114.354})
611  .CubicCurveTo({268.172, 114.412}, {267.959, 114.478},
612  {267.752, 114.54})
613  .CubicCurveTo({263.349, 115.964}, {258.058, 117.695},
614  {253.564, 119.252})
615  .CubicCurveTo({253.556, 119.255}, {253.547, 119.258},
616  {253.538, 119.261})
617  .CubicCurveTo({251.844, 119.849}, {250.056, 120.474},
618  {248.189, 121.131})
619  .CubicCurveTo({248, 121.197}, {247.812, 121.264}, {247.621, 121.331})
620  .CubicCurveTo({247.079, 121.522}, {246.531, 121.715},
621  {245.975, 121.912})
622  .CubicCurveTo({245.554, 122.06}, {245.126, 122.212},
623  {244.698, 122.364})
624  .CubicCurveTo({244.071, 122.586}, {243.437, 122.811},
625  {242.794, 123.04})
626  .CubicCurveTo({242.189, 123.255}, {241.58, 123.472},
627  {240.961, 123.693})
628  .CubicCurveTo({240.659, 123.801}, {240.357, 123.909},
629  {240.052, 124.018})
630  .CubicCurveTo({239.12, 124.351}, {238.18, 124.687}, {237.22, 125.032})
631  .LineTo({237.164, 125.003})
632  .CubicCurveTo({236.709, 125.184}, {236.262, 125.358},
633  {235.81, 125.538})
634  .CubicCurveTo({235.413, 125.68}, {234.994, 125.832},
635  {234.592, 125.977})
636  .CubicCurveTo({234.592, 125.977}, {234.591, 125.977},
637  {234.59, 125.977})
638  .CubicCurveTo({222.206, 130.435}, {207.708, 135.753},
639  {192.381, 141.429})
640  .CubicCurveTo({162.77, 151.336}, {122.17, 156.894}, {84.1123, 160})
641  .LineTo({360, 160})
642  .LineTo({360, 119.256})
643  .LineTo({360, 106.332})
644  .LineTo({360, 96.6307})
645  .CubicCurveTo({359.978, 96.6317}, {359.956, 96.6326},
646  {359.934, 96.6335})
647  .Close()
648  .MoveTo({337.336, 124.143})
649  .CubicCurveTo({337.274, 122.359}, {338.903, 121.511},
650  {338.903, 121.511})
651  .CubicCurveTo({338.903, 121.511}, {338.96, 123.303},
652  {337.336, 124.143})
653  .Close()
654  .MoveTo({340.082, 121.849})
655  .CubicCurveTo({340.074, 121.917}, {340.062, 121.992},
656  {340.046, 122.075})
657  .CubicCurveTo({340.039, 122.109}, {340.031, 122.142},
658  {340.023, 122.177})
659  .CubicCurveTo({340.005, 122.26}, {339.98, 122.346},
660  {339.952, 122.437})
661  .CubicCurveTo({339.941, 122.473}, {339.931, 122.507},
662  {339.918, 122.544})
663  .CubicCurveTo({339.873, 122.672}, {339.819, 122.804},
664  {339.75, 122.938})
665  .CubicCurveTo({339.747, 122.944}, {339.743, 122.949},
666  {339.74, 122.955})
667  .CubicCurveTo({339.674, 123.08}, {339.593, 123.205},
668  {339.501, 123.328})
669  .CubicCurveTo({339.473, 123.366}, {339.441, 123.401},
670  {339.41, 123.438})
671  .CubicCurveTo({339.332, 123.534}, {339.243, 123.625},
672  {339.145, 123.714})
673  .CubicCurveTo({339.105, 123.75}, {339.068, 123.786},
674  {339.025, 123.821})
675  .CubicCurveTo({338.881, 123.937}, {338.724, 124.048},
676  {338.539, 124.143})
677  .CubicCurveTo({338.532, 123.959}, {338.554, 123.79},
678  {338.58, 123.626})
679  .CubicCurveTo({338.58, 123.625}, {338.58, 123.625}, {338.58, 123.625})
680  .CubicCurveTo({338.607, 123.455}, {338.65, 123.299},
681  {338.704, 123.151})
682  .CubicCurveTo({338.708, 123.14}, {338.71, 123.127},
683  {338.714, 123.117})
684  .CubicCurveTo({338.769, 122.971}, {338.833, 122.838},
685  {338.905, 122.712})
686  .CubicCurveTo({338.911, 122.702}, {338.916, 122.69200000000001},
687  {338.922, 122.682})
688  .CubicCurveTo({338.996, 122.557}, {339.072, 122.444},
689  {339.155, 122.34})
690  .CubicCurveTo({339.161, 122.333}, {339.166, 122.326},
691  {339.172, 122.319})
692  .CubicCurveTo({339.256, 122.215}, {339.339, 122.12},
693  {339.425, 122.037})
694  .CubicCurveTo({339.428, 122.033}, {339.431, 122.03},
695  {339.435, 122.027})
696  .CubicCurveTo({339.785, 121.687}, {340.106, 121.511},
697  {340.106, 121.511})
698  .CubicCurveTo({340.106, 121.511}, {340.107, 121.645},
699  {340.082, 121.849})
700  .Close()
701  .MoveTo({340.678, 113.245})
702  .CubicCurveTo({340.594, 113.488}, {340.356, 113.655},
703  {340.135, 113.775})
704  .CubicCurveTo({339.817, 113.948}, {339.465, 114.059},
705  {339.115, 114.151})
706  .CubicCurveTo({338.251, 114.379}, {337.34, 114.516},
707  {336.448, 114.516})
708  .CubicCurveTo({335.761, 114.516}, {335.072, 114.527},
709  {334.384, 114.513})
710  .CubicCurveTo({334.125, 114.508}, {333.862, 114.462},
711  {333.605, 114.424})
712  .CubicCurveTo({332.865, 114.318}, {332.096, 114.184},
713  {331.41, 113.883})
714  .CubicCurveTo({330.979, 113.695}, {330.442, 113.34},
715  {330.672, 112.813})
716  .CubicCurveTo({331.135, 111.755}, {333.219, 112.946},
717  {334.526, 113.833})
718  .CubicCurveTo({334.54, 113.816}, {334.554, 113.8}, {334.569, 113.784})
719  .CubicCurveTo({333.38, 112.708}, {331.749, 110.985},
720  {332.76, 110.402})
721  .CubicCurveTo({333.769, 109.82}, {334.713, 111.93},
722  {335.228, 113.395})
723  .CubicCurveTo({334.915, 111.889}, {334.59, 109.636},
724  {335.661, 109.592})
725  .CubicCurveTo({336.733, 109.636}, {336.408, 111.889},
726  {336.07, 113.389})
727  .CubicCurveTo({336.609, 111.93}, {337.553, 109.82},
728  {338.563, 110.402})
729  .CubicCurveTo({339.574, 110.984}, {337.942, 112.708},
730  {336.753, 113.784})
731  .CubicCurveTo({336.768, 113.8}, {336.782, 113.816},
732  {336.796, 113.833})
733  .CubicCurveTo({338.104, 112.946}, {340.187, 111.755},
734  {340.65, 112.813})
735  .CubicCurveTo({340.71, 112.95}, {340.728, 113.102},
736  {340.678, 113.245})
737  .Close()
738  .MoveTo({346.357, 106.771})
739  .CubicCurveTo({346.295, 104.987}, {347.924, 104.139},
740  {347.924, 104.139})
741  .CubicCurveTo({347.924, 104.139}, {347.982, 105.931},
742  {346.357, 106.771})
743  .Close()
744  .MoveTo({347.56, 106.771})
745  .CubicCurveTo({347.498, 104.987}, {349.127, 104.139},
746  {349.127, 104.139})
747  .CubicCurveTo({349.127, 104.139}, {349.185, 105.931},
748  {347.56, 106.771})
749  .Close()
750  .TakePath();
751  Entity entity;
752  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
753  entity.SetContents(SolidColorContents::Make(std::move(path), Color::Red()));
754  ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
755 }

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() [289/384]

impeller::testing::TEST_P ( EntityTest  ,
CubicCurveTest   
)

Definition at line 461 of file entity_unittests.cc.

461  {
462  // Compare with https://fiddle.skia.org/c/b3625f26122c9de7afe7794fcf25ead3
463  Path path =
464  PathBuilder{}
465  .MoveTo({237.164, 125.003})
466  .CubicCurveTo({236.709, 125.184}, {236.262, 125.358},
467  {235.81, 125.538})
468  .CubicCurveTo({235.413, 125.68}, {234.994, 125.832},
469  {234.592, 125.977})
470  .CubicCurveTo({234.592, 125.977}, {234.591, 125.977},
471  {234.59, 125.977})
472  .CubicCurveTo({222.206, 130.435}, {207.708, 135.753},
473  {192.381, 141.429})
474  .CubicCurveTo({162.77, 151.336}, {122.17, 156.894}, {84.1123, 160})
475  .Close()
476  .TakePath();
477  Entity entity;
478  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
479  entity.SetContents(SolidColorContents::Make(std::move(path), Color::Red()));
480  ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
481 }

References impeller::Close(), impeller::SolidColorContents::Make(), impeller::Matrix::MakeScale(), impeller::PathBuilder::MoveTo(), impeller::Color::Red(), impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [290/384]

impeller::testing::TEST_P ( EntityTest  ,
DecalSpecializationAppliedToMorphologyFilter   
)

Definition at line 2564 of file entity_unittests.cc.

2564  {
2565  auto content_context =
2566  ContentContext(GetContext(), TypographerContextSkia::Make());
2567 
2568  auto default_color_burn = content_context.GetMorphologyFilterPipeline({});
2569 
2570  auto decal_supported = static_cast<Scalar>(
2571  GetContext()->GetCapabilities()->SupportsDecalSamplerAddressMode());
2572  std::vector<Scalar> expected_constants = {decal_supported};
2573  ASSERT_EQ(default_color_burn->GetDescriptor().GetSpecializationConstants(),
2574  expected_constants);
2575 }

References impeller::TypographerContextSkia::Make().

◆ TEST_P() [291/384]

impeller::testing::TEST_P ( EntityTest  ,
DoesNotCullEntitiesByDefault   
)

Definition at line 1631 of file entity_unittests.cc.

1631  {
1632  auto fill = std::make_shared<SolidColorContents>();
1633  fill->SetColor(Color::CornflowerBlue());
1634  fill->SetGeometry(
1635  Geometry::MakeRect(Rect::MakeLTRB(-1000, -1000, -900, -900)));
1636 
1637  Entity entity;
1638  entity.SetContents(fill);
1639 
1640  // Even though the entity is offscreen, this should still render because we do
1641  // not compute the coverage intersection by default.
1642  EXPECT_TRUE(entity.ShouldRender(Rect::MakeLTRB(0, 0, 100, 100)));
1643 }

References impeller::Color::CornflowerBlue(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Geometry::MakeRect(), impeller::Entity::SetContents(), and impeller::Entity::ShouldRender().

◆ TEST_P() [292/384]

impeller::testing::TEST_P ( EntityTest  ,
DrawAtlasNoColor   
)

Definition at line 1360 of file entity_unittests.cc.

1360  {
1361  // Draws the image as four squares stiched together.
1362  auto atlas = CreateTextureForFixture("bay_bridge.jpg");
1363  auto size = atlas->GetSize();
1364  // Divide image into four quadrants.
1365  Scalar half_width = size.width / 2;
1366  Scalar half_height = size.height / 2;
1367  std::vector<Rect> texture_coordinates = {
1368  Rect::MakeLTRB(0, 0, half_width, half_height),
1369  Rect::MakeLTRB(half_width, 0, size.width, half_height),
1370  Rect::MakeLTRB(0, half_height, half_width, size.height),
1371  Rect::MakeLTRB(half_width, half_height, size.width, size.height)};
1372  // Position quadrants adjacent to eachother.
1373  std::vector<Matrix> transforms = {
1374  Matrix::MakeTranslation({0, 0, 0}),
1375  Matrix::MakeTranslation({half_width, 0, 0}),
1376  Matrix::MakeTranslation({0, half_height, 0}),
1377  Matrix::MakeTranslation({half_width, half_height, 0})};
1378  std::shared_ptr<AtlasContents> contents = std::make_shared<AtlasContents>();
1379 
1380  contents->SetTransforms(std::move(transforms));
1381  contents->SetTextureCoordinates(std::move(texture_coordinates));
1382  contents->SetTexture(atlas);
1383  contents->SetBlendMode(BlendMode::kSource);
1384 
1385  Entity e;
1386  e.SetTransform(Matrix::MakeScale(GetContentScale()));
1387  e.SetContents(contents);
1388 
1389  ASSERT_TRUE(OpenPlaygroundHere(std::move(e)));
1390 }

References impeller::kSource, impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [293/384]

impeller::testing::TEST_P ( EntityTest  ,
DrawAtlasNoColorFullSize   
)

Definition at line 1536 of file entity_unittests.cc.

1536  {
1537  auto atlas = CreateTextureForFixture("bay_bridge.jpg");
1538  auto size = atlas->GetSize();
1539  std::vector<Rect> texture_coordinates = {
1540  Rect::MakeLTRB(0, 0, size.width, size.height)};
1541  std::vector<Matrix> transforms = {Matrix::MakeTranslation({0, 0, 0})};
1542  std::shared_ptr<AtlasContents> contents = std::make_shared<AtlasContents>();
1543 
1544  contents->SetTransforms(std::move(transforms));
1545  contents->SetTextureCoordinates(std::move(texture_coordinates));
1546  contents->SetTexture(atlas);
1547  contents->SetBlendMode(BlendMode::kSource);
1548 
1549  Entity e;
1550  e.SetTransform(Matrix::MakeScale(GetContentScale()));
1551  e.SetContents(contents);
1552 
1553  ASSERT_TRUE(OpenPlaygroundHere(std::move(e)));
1554 }

References impeller::kSource, impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [294/384]

impeller::testing::TEST_P ( EntityTest  ,
DrawAtlasUsesProvidedCullRectForCoverage   
)

Definition at line 1463 of file entity_unittests.cc.

1463  {
1464  auto atlas = CreateTextureForFixture("bay_bridge.jpg");
1465  auto size = atlas->GetSize();
1466 
1467  Scalar half_width = size.width / 2;
1468  Scalar half_height = size.height / 2;
1469  std::vector<Rect> texture_coordinates = {
1470  Rect::MakeLTRB(0, 0, half_width, half_height),
1471  Rect::MakeLTRB(half_width, 0, size.width, half_height),
1472  Rect::MakeLTRB(0, half_height, half_width, size.height),
1473  Rect::MakeLTRB(half_width, half_height, size.width, size.height)};
1474  std::vector<Matrix> transforms = {
1475  Matrix::MakeTranslation({0, 0, 0}),
1476  Matrix::MakeTranslation({half_width, 0, 0}),
1477  Matrix::MakeTranslation({0, half_height, 0}),
1478  Matrix::MakeTranslation({half_width, half_height, 0})};
1479 
1480  std::shared_ptr<AtlasContents> contents = std::make_shared<AtlasContents>();
1481 
1482  contents->SetTransforms(std::move(transforms));
1483  contents->SetTextureCoordinates(std::move(texture_coordinates));
1484  contents->SetTexture(atlas);
1485  contents->SetBlendMode(BlendMode::kSource);
1486 
1487  auto transform = Matrix::MakeScale(GetContentScale());
1488  Entity e;
1489  e.SetTransform(transform);
1490  e.SetContents(contents);
1491 
1492  ASSERT_EQ(contents->GetCoverage(e).value(),
1493  Rect::MakeSize(size).TransformBounds(transform));
1494 
1495  contents->SetCullRect(Rect::MakeLTRB(0, 0, 10, 10));
1496 
1497  ASSERT_EQ(contents->GetCoverage(e).value(),
1498  Rect::MakeLTRB(0, 0, 10, 10).TransformBounds(transform));
1499 }

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() [295/384]

impeller::testing::TEST_P ( EntityTest  ,
DrawAtlasWithColorAdvanced   
)

Definition at line 1392 of file entity_unittests.cc.

1392  {
1393  // Draws the image as four squares stiched together.
1394  auto atlas = CreateTextureForFixture("bay_bridge.jpg");
1395  auto size = atlas->GetSize();
1396  // Divide image into four quadrants.
1397  Scalar half_width = size.width / 2;
1398  Scalar half_height = size.height / 2;
1399  std::vector<Rect> texture_coordinates = {
1400  Rect::MakeLTRB(0, 0, half_width, half_height),
1401  Rect::MakeLTRB(half_width, 0, size.width, half_height),
1402  Rect::MakeLTRB(0, half_height, half_width, size.height),
1403  Rect::MakeLTRB(half_width, half_height, size.width, size.height)};
1404  // Position quadrants adjacent to eachother.
1405  std::vector<Matrix> transforms = {
1406  Matrix::MakeTranslation({0, 0, 0}),
1407  Matrix::MakeTranslation({half_width, 0, 0}),
1408  Matrix::MakeTranslation({0, half_height, 0}),
1409  Matrix::MakeTranslation({half_width, half_height, 0})};
1410  std::vector<Color> colors = {Color::Red(), Color::Green(), Color::Blue(),
1411  Color::Yellow()};
1412  std::shared_ptr<AtlasContents> contents = std::make_shared<AtlasContents>();
1413 
1414  contents->SetTransforms(std::move(transforms));
1415  contents->SetTextureCoordinates(std::move(texture_coordinates));
1416  contents->SetTexture(atlas);
1417  contents->SetColors(colors);
1418  contents->SetBlendMode(BlendMode::kModulate);
1419 
1420  Entity e;
1421  e.SetTransform(Matrix::MakeScale(GetContentScale()));
1422  e.SetContents(contents);
1423 
1424  ASSERT_TRUE(OpenPlaygroundHere(std::move(e)));
1425 }

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() [296/384]

impeller::testing::TEST_P ( EntityTest  ,
DrawAtlasWithColorSimple   
)

Definition at line 1427 of file entity_unittests.cc.

1427  {
1428  // Draws the image as four squares stiched together. Because blend modes
1429  // aren't implented this ends up as four solid color blocks.
1430  auto atlas = CreateTextureForFixture("bay_bridge.jpg");
1431  auto size = atlas->GetSize();
1432  // Divide image into four quadrants.
1433  Scalar half_width = size.width / 2;
1434  Scalar half_height = size.height / 2;
1435  std::vector<Rect> texture_coordinates = {
1436  Rect::MakeLTRB(0, 0, half_width, half_height),
1437  Rect::MakeLTRB(half_width, 0, size.width, half_height),
1438  Rect::MakeLTRB(0, half_height, half_width, size.height),
1439  Rect::MakeLTRB(half_width, half_height, size.width, size.height)};
1440  // Position quadrants adjacent to eachother.
1441  std::vector<Matrix> transforms = {
1442  Matrix::MakeTranslation({0, 0, 0}),
1443  Matrix::MakeTranslation({half_width, 0, 0}),
1444  Matrix::MakeTranslation({0, half_height, 0}),
1445  Matrix::MakeTranslation({half_width, half_height, 0})};
1446  std::vector<Color> colors = {Color::Red(), Color::Green(), Color::Blue(),
1447  Color::Yellow()};
1448  std::shared_ptr<AtlasContents> contents = std::make_shared<AtlasContents>();
1449 
1450  contents->SetTransforms(std::move(transforms));
1451  contents->SetTextureCoordinates(std::move(texture_coordinates));
1452  contents->SetTexture(atlas);
1453  contents->SetColors(colors);
1454  contents->SetBlendMode(BlendMode::kSourceATop);
1455 
1456  Entity e;
1457  e.SetTransform(Matrix::MakeScale(GetContentScale()));
1458  e.SetContents(contents);
1459 
1460  ASSERT_TRUE(OpenPlaygroundHere(std::move(e)));
1461 }

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() [297/384]

impeller::testing::TEST_P ( EntityTest  ,
DrawAtlasWithOpacity   
)

Definition at line 1501 of file entity_unittests.cc.

1501  {
1502  // Draws the image as four squares stiched together slightly
1503  // opaque
1504  auto atlas = CreateTextureForFixture("bay_bridge.jpg");
1505  auto size = atlas->GetSize();
1506  // Divide image into four quadrants.
1507  Scalar half_width = size.width / 2;
1508  Scalar half_height = size.height / 2;
1509  std::vector<Rect> texture_coordinates = {
1510  Rect::MakeLTRB(0, 0, half_width, half_height),
1511  Rect::MakeLTRB(half_width, 0, size.width, half_height),
1512  Rect::MakeLTRB(0, half_height, half_width, size.height),
1513  Rect::MakeLTRB(half_width, half_height, size.width, size.height)};
1514  // Position quadrants adjacent to eachother.
1515  std::vector<Matrix> transforms = {
1516  Matrix::MakeTranslation({0, 0, 0}),
1517  Matrix::MakeTranslation({half_width, 0, 0}),
1518  Matrix::MakeTranslation({0, half_height, 0}),
1519  Matrix::MakeTranslation({half_width, half_height, 0})};
1520 
1521  std::shared_ptr<AtlasContents> contents = std::make_shared<AtlasContents>();
1522 
1523  contents->SetTransforms(std::move(transforms));
1524  contents->SetTextureCoordinates(std::move(texture_coordinates));
1525  contents->SetTexture(atlas);
1526  contents->SetBlendMode(BlendMode::kSource);
1527  contents->SetAlpha(0.5);
1528 
1529  Entity e;
1530  e.SetTransform(Matrix::MakeScale(GetContentScale()));
1531  e.SetContents(contents);
1532 
1533  ASSERT_TRUE(OpenPlaygroundHere(std::move(e)));
1534 }

References impeller::kSource, impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [298/384]

impeller::testing::TEST_P ( EntityTest  ,
EntityPassCanMergeSubpassIntoParent   
)

Definition at line 145 of file entity_unittests.cc.

145  {
146  // Both a red and a blue box should appear if the pass merging has worked
147  // correctly.
148 
149  EntityPass pass;
150  auto subpass = CreatePassWithRectPath(Rect::MakeLTRB(0, 0, 100, 100),
151  Rect::MakeLTRB(50, 50, 150, 150), true);
152  pass.AddSubpass(std::move(subpass));
153 
154  Entity entity;
155  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
156  auto contents = std::make_unique<SolidColorContents>();
157  contents->SetGeometry(Geometry::MakeRect(Rect::MakeLTRB(100, 100, 200, 200)));
158  contents->SetColor(Color::Blue());
159  entity.SetContents(std::move(contents));
160 
161  pass.AddEntity(std::move(entity));
162 
163  ASSERT_TRUE(OpenPlaygroundHere(pass));
164 }

References impeller::EntityPass::AddEntity(), impeller::EntityPass::AddSubpass(), impeller::Color::Blue(), CreatePassWithRectPath(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Geometry::MakeRect(), impeller::Matrix::MakeScale(), impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [299/384]

impeller::testing::TEST_P ( EntityTest  ,
EntityPassCoverageRespectsCoverageLimit   
)

Definition at line 166 of file entity_unittests.cc.

166  {
167  // Rect is drawn entirely in negative area.
168  auto pass = CreatePassWithRectPath(Rect::MakeLTRB(-200, -200, -100, -100),
169  std::nullopt);
170 
171  // Without coverage limit.
172  {
173  auto pass_coverage = pass->GetElementsCoverage(std::nullopt);
174  ASSERT_TRUE(pass_coverage.has_value());
175  ASSERT_RECT_NEAR(pass_coverage.value(),
176  Rect::MakeLTRB(-200, -200, -100, -100));
177  }
178 
179  // With limit that doesn't overlap.
180  {
181  auto pass_coverage =
182  pass->GetElementsCoverage(Rect::MakeLTRB(0, 0, 100, 100));
183  ASSERT_FALSE(pass_coverage.has_value());
184  }
185 
186  // With limit that partially overlaps.
187  {
188  auto pass_coverage =
189  pass->GetElementsCoverage(Rect::MakeLTRB(-150, -150, 0, 0));
190  ASSERT_TRUE(pass_coverage.has_value());
191  ASSERT_RECT_NEAR(pass_coverage.value(),
192  Rect::MakeLTRB(-150, -150, -100, -100));
193  }
194 }

References ASSERT_RECT_NEAR, CreatePassWithRectPath(), and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST_P() [300/384]

impeller::testing::TEST_P ( EntityTest  ,
EntityPassRespectsSubpassBoundsLimit   
)

Definition at line 118 of file entity_unittests.cc.

118  {
119  EntityPass pass;
120 
121  auto subpass0 = CreatePassWithRectPath(Rect::MakeLTRB(0, 0, 100, 100),
122  Rect::MakeLTRB(50, 50, 150, 150));
123  auto subpass1 = CreatePassWithRectPath(Rect::MakeLTRB(500, 500, 1000, 1000),
124  Rect::MakeLTRB(800, 800, 900, 900));
125 
126  auto subpass0_coverage =
127  pass.GetSubpassCoverage(*subpass0.get(), std::nullopt);
128  ASSERT_TRUE(subpass0_coverage.has_value());
129  ASSERT_RECT_NEAR(subpass0_coverage.value(), Rect::MakeLTRB(50, 50, 100, 100));
130 
131  auto subpass1_coverage =
132  pass.GetSubpassCoverage(*subpass1.get(), std::nullopt);
133  ASSERT_TRUE(subpass1_coverage.has_value());
134  ASSERT_RECT_NEAR(subpass1_coverage.value(),
135  Rect::MakeLTRB(800, 800, 900, 900));
136 
137  pass.AddSubpass(std::move(subpass0));
138  pass.AddSubpass(std::move(subpass1));
139 
140  auto coverage = pass.GetElementsCoverage(std::nullopt);
141  ASSERT_TRUE(coverage.has_value());
142  ASSERT_RECT_NEAR(coverage.value(), Rect::MakeLTRB(50, 50, 900, 900));
143 }

References impeller::EntityPass::AddSubpass(), ASSERT_RECT_NEAR, CreatePassWithRectPath(), impeller::EntityPass::GetElementsCoverage(), impeller::EntityPass::GetSubpassCoverage(), and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST_P() [301/384]

impeller::testing::TEST_P ( EntityTest  ,
FilterCoverageRespectsCropRect   
)

Definition at line 196 of file entity_unittests.cc.

196  {
197  auto image = CreateTextureForFixture("boston.jpg");
198  auto filter = ColorFilterContents::MakeBlend(BlendMode::kSoftLight,
199  FilterInput::Make({image}));
200 
201  // Without the crop rect (default behavior).
202  {
203  auto actual = filter->GetCoverage({});
204  auto expected = Rect::MakeSize(image->GetSize());
205 
206  ASSERT_TRUE(actual.has_value());
207  ASSERT_RECT_NEAR(actual.value(), expected);
208  }
209 
210  // With the crop rect.
211  {
212  auto expected = Rect::MakeLTRB(50, 50, 100, 100);
213  filter->SetCoverageHint(expected);
214  auto actual = filter->GetCoverage({});
215 
216  ASSERT_TRUE(actual.has_value());
217  ASSERT_RECT_NEAR(actual.value(), expected);
218  }
219 }

References ASSERT_RECT_NEAR, impeller::kSoftLight, impeller::FilterInput::Make(), impeller::ColorFilterContents::MakeBlend(), impeller::TRect< Scalar >::MakeLTRB(), and impeller::TRect< Scalar >::MakeSize().

◆ TEST_P() [302/384]

impeller::testing::TEST_P ( EntityTest  ,
Filters   
)

Definition at line 960 of file entity_unittests.cc.

960  {
961  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
962  auto boston = CreateTextureForFixture("boston.jpg");
963  auto kalimba = CreateTextureForFixture("kalimba.jpg");
964  ASSERT_TRUE(bridge && boston && kalimba);
965 
966  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
967  auto fi_bridge = FilterInput::Make(bridge);
968  auto fi_boston = FilterInput::Make(boston);
969  auto fi_kalimba = FilterInput::Make(kalimba);
970 
971  std::shared_ptr<FilterContents> blend0 = ColorFilterContents::MakeBlend(
972  BlendMode::kModulate, {fi_kalimba, fi_boston});
973 
974  auto blend1 = ColorFilterContents::MakeBlend(
975  BlendMode::kScreen,
976  {FilterInput::Make(blend0), fi_bridge, fi_bridge, fi_bridge});
977 
978  Entity entity;
979  entity.SetTransform(Matrix::MakeScale(GetContentScale()) *
980  Matrix::MakeTranslation({500, 300}) *
981  Matrix::MakeScale(Vector2{0.5, 0.5}));
982  entity.SetContents(blend1);
983  return entity.Render(context, pass);
984  };
985  ASSERT_TRUE(OpenPlaygroundHere(callback));
986 }

References impeller::kModulate, impeller::kScreen, impeller::FilterInput::Make(), impeller::ColorFilterContents::MakeBlend(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), and impeller::Entity::SetTransform().

◆ TEST_P() [303/384]

impeller::testing::TEST_P ( EntityTest  ,
FramebufferFetchPipelinesDeclareUsage   
)

Definition at line 2577 of file entity_unittests.cc.

2577  {
2578  auto content_context =
2579  ContentContext(GetContext(), TypographerContextSkia::Make());
2580  if (!content_context.GetDeviceCapabilities().SupportsFramebufferFetch()) {
2581  GTEST_SKIP() << "Framebuffer fetch not supported.";
2582  }
2583 
2584  ContentContextOptions options;
2585  options.color_attachment_pixel_format = PixelFormat::kR8G8B8A8UNormInt;
2586  auto color_burn =
2587  content_context.GetFramebufferBlendColorBurnPipeline(options);
2588 
2589  EXPECT_TRUE(color_burn->GetDescriptor().UsesSubpassInput());
2590 }

References impeller::ContentContextOptions::color_attachment_pixel_format, impeller::kR8G8B8A8UNormInt, and impeller::TypographerContextSkia::Make().

◆ TEST_P() [304/384]

impeller::testing::TEST_P ( EntityTest  ,
GaussianBlurFilter   
)

Definition at line 988 of file entity_unittests.cc.

988  {
989  auto boston = CreateTextureForFixture("boston.jpg");
990  ASSERT_TRUE(boston);
991 
992  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
993  const char* input_type_names[] = {"Texture", "Solid Color"};
994  const char* blur_type_names[] = {"Image blur", "Mask blur"};
995  const char* pass_variation_names[] = {"New", "2D Directional",
996  "Directional"};
997  const char* blur_style_names[] = {"Normal", "Solid", "Outer", "Inner"};
998  const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
999  const FilterContents::BlurStyle blur_styles[] = {
1000  FilterContents::BlurStyle::kNormal, FilterContents::BlurStyle::kSolid,
1001  FilterContents::BlurStyle::kOuter, FilterContents::BlurStyle::kInner};
1002  const Entity::TileMode tile_modes[] = {
1003  Entity::TileMode::kClamp, Entity::TileMode::kRepeat,
1004  Entity::TileMode::kMirror, Entity::TileMode::kDecal};
1005 
1006  // UI state.
1007  static int selected_input_type = 0;
1008  static Color input_color = Color::Black();
1009  static int selected_blur_type = 0;
1010  static int selected_pass_variation = 0;
1011  static bool combined_sigma = false;
1012  static float blur_amount_coarse[2] = {0, 0};
1013  static float blur_amount_fine[2] = {10, 10};
1014  static int selected_blur_style = 0;
1015  static int selected_tile_mode = 3;
1016  static Color cover_color(1, 0, 0, 0.2);
1017  static Color bounds_color(0, 1, 0, 0.1);
1018  static float offset[2] = {500, 400};
1019  static float rotation = 0;
1020  static float scale[2] = {0.65, 0.65};
1021  static float skew[2] = {0, 0};
1022  static float path_rect[4] = {0, 0,
1023  static_cast<float>(boston->GetSize().width),
1024  static_cast<float>(boston->GetSize().height)};
1025 
1026  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1027  {
1028  ImGui::Combo("Input type", &selected_input_type, input_type_names,
1029  sizeof(input_type_names) / sizeof(char*));
1030  if (selected_input_type == 0) {
1031  ImGui::SliderFloat("Input opacity", &input_color.alpha, 0, 1);
1032  } else {
1033  ImGui::ColorEdit4("Input color",
1034  reinterpret_cast<float*>(&input_color));
1035  }
1036  ImGui::Combo("Blur type", &selected_blur_type, blur_type_names,
1037  sizeof(blur_type_names) / sizeof(char*));
1038  if (selected_blur_type == 0) {
1039  ImGui::Combo("Pass variation", &selected_pass_variation,
1040  pass_variation_names,
1041  sizeof(pass_variation_names) / sizeof(char*));
1042  }
1043  ImGui::Checkbox("Combined sigma", &combined_sigma);
1044  if (combined_sigma) {
1045  ImGui::SliderFloat("Sigma (coarse)", blur_amount_coarse, 0, 1000);
1046  ImGui::SliderFloat("Sigma (fine)", blur_amount_fine, 0, 10);
1047  blur_amount_coarse[1] = blur_amount_coarse[0];
1048  blur_amount_fine[1] = blur_amount_fine[0];
1049  } else {
1050  ImGui::SliderFloat2("Sigma (coarse)", blur_amount_coarse, 0, 1000);
1051  ImGui::SliderFloat2("Sigma (fine)", blur_amount_fine, 0, 10);
1052  }
1053  ImGui::Combo("Blur style", &selected_blur_style, blur_style_names,
1054  sizeof(blur_style_names) / sizeof(char*));
1055  ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
1056  sizeof(tile_mode_names) / sizeof(char*));
1057  ImGui::ColorEdit4("Cover color", reinterpret_cast<float*>(&cover_color));
1058  ImGui::ColorEdit4("Bounds color",
1059  reinterpret_cast<float*>(&bounds_color));
1060  ImGui::SliderFloat2("Translation", offset, 0,
1061  pass.GetRenderTargetSize().width);
1062  ImGui::SliderFloat("Rotation", &rotation, 0, kPi * 2);
1063  ImGui::SliderFloat2("Scale", scale, 0, 3);
1064  ImGui::SliderFloat2("Skew", skew, -3, 3);
1065  ImGui::SliderFloat4("Path XYWH", path_rect, -1000, 1000);
1066  }
1067  ImGui::End();
1068 
1069  auto blur_sigma_x = Sigma{blur_amount_coarse[0] + blur_amount_fine[0]};
1070  auto blur_sigma_y = Sigma{blur_amount_coarse[1] + blur_amount_fine[1]};
1071 
1072  std::shared_ptr<Contents> input;
1073  Size input_size;
1074 
1075  auto input_rect =
1076  Rect::MakeXYWH(path_rect[0], path_rect[1], path_rect[2], path_rect[3]);
1077  if (selected_input_type == 0) {
1078  auto texture = std::make_shared<TextureContents>();
1079  texture->SetSourceRect(Rect::MakeSize(boston->GetSize()));
1080  texture->SetDestinationRect(input_rect);
1081  texture->SetTexture(boston);
1082  texture->SetOpacity(input_color.alpha);
1083 
1084  input = texture;
1085  input_size = input_rect.GetSize();
1086  } else {
1087  auto fill = std::make_shared<SolidColorContents>();
1088  fill->SetColor(input_color);
1089  fill->SetGeometry(
1090  Geometry::MakeFillPath(PathBuilder{}.AddRect(input_rect).TakePath()));
1091 
1092  input = fill;
1093  input_size = input_rect.GetSize();
1094  }
1095 
1096  std::shared_ptr<FilterContents> blur;
1097  switch (selected_pass_variation) {
1098  case 0:
1099  blur = std::make_shared<GaussianBlurFilterContents>(
1100  blur_sigma_x.sigma, blur_sigma_y.sigma,
1101  tile_modes[selected_tile_mode]);
1102  blur->SetInputs({FilterInput::Make(input)});
1103  break;
1104  case 1:
1105  blur = FilterContents::MakeGaussianBlur(
1106  FilterInput::Make(input), blur_sigma_x, blur_sigma_y,
1107  blur_styles[selected_blur_style], tile_modes[selected_tile_mode]);
1108  break;
1109  case 2: {
1110  Vector2 blur_vector(blur_sigma_x.sigma, blur_sigma_y.sigma);
1111  blur = FilterContents::MakeDirectionalGaussianBlur(
1112  FilterInput::Make(input), Sigma{blur_vector.GetLength()},
1113  blur_vector.Normalize());
1114  break;
1115  }
1116  };
1117  FML_CHECK(blur);
1118 
1119  auto mask_blur = FilterContents::MakeBorderMaskBlur(
1120  FilterInput::Make(input), blur_sigma_x, blur_sigma_y,
1121  blur_styles[selected_blur_style]);
1122 
1123  auto ctm = Matrix::MakeScale(GetContentScale()) *
1124  Matrix::MakeTranslation(Vector3(offset[0], offset[1])) *
1125  Matrix::MakeRotationZ(Radians(rotation)) *
1126  Matrix::MakeScale(Vector2(scale[0], scale[1])) *
1127  Matrix::MakeSkew(skew[0], skew[1]) *
1128  Matrix::MakeTranslation(-Point(input_size) / 2);
1129 
1130  auto target_contents = selected_blur_type == 0 ? blur : mask_blur;
1131 
1132  Entity entity;
1133  entity.SetContents(target_contents);
1134  entity.SetTransform(ctm);
1135 
1136  entity.Render(context, pass);
1137 
1138  // Renders a red "cover" rectangle that shows the original position of the
1139  // unfiltered input.
1140  Entity cover_entity;
1141  cover_entity.SetContents(SolidColorContents::Make(
1142  PathBuilder{}.AddRect(input_rect).TakePath(), cover_color));
1143  cover_entity.SetTransform(ctm);
1144 
1145  cover_entity.Render(context, pass);
1146 
1147  // Renders a green bounding rect of the target filter.
1148  Entity bounds_entity;
1149  std::optional<Rect> target_contents_coverage =
1150  target_contents->GetCoverage(entity);
1151  if (target_contents_coverage.has_value()) {
1152  bounds_entity.SetContents(SolidColorContents::Make(
1153  PathBuilder{}
1154  .AddRect(target_contents->GetCoverage(entity).value())
1155  .TakePath(),
1156  bounds_color));
1157  bounds_entity.SetTransform(Matrix());
1158 
1159  bounds_entity.Render(context, pass);
1160  }
1161 
1162  return true;
1163  };
1164  ASSERT_TRUE(OpenPlaygroundHere(callback));
1165 }

References impeller::PathBuilder::AddRect(), impeller::Color::alpha, impeller::Color::Black(), impeller::Entity::GetCoverage(), impeller::TPoint< T >::GetLength(), impeller::Entity::kClamp, impeller::Entity::kDecal, impeller::FilterContents::kInner, impeller::Entity::kMirror, impeller::FilterContents::kNormal, impeller::FilterContents::kOuter, impeller::kPi, impeller::Entity::kRepeat, impeller::FilterContents::kSolid, impeller::SolidColorContents::Make(), impeller::FilterInput::Make(), impeller::FilterContents::MakeBorderMaskBlur(), impeller::FilterContents::MakeDirectionalGaussianBlur(), impeller::Geometry::MakeFillPath(), impeller::FilterContents::MakeGaussianBlur(), impeller::Matrix::MakeRotationZ(), impeller::Matrix::MakeScale(), impeller::TRect< Scalar >::MakeSize(), impeller::Matrix::MakeSkew(), impeller::Matrix::MakeTranslation(), impeller::TRect< Scalar >::MakeXYWH(), impeller::TPoint< T >::Normalize(), impeller::Entity::Render(), impeller::Entity::SetContents(), impeller::Entity::SetTransform(), and impeller::PathBuilder::TakePath().

◆ TEST_P() [305/384]

impeller::testing::TEST_P ( EntityTest  ,
GeometryBoundsAreTransformed   
)

Definition at line 249 of file entity_unittests.cc.

249  {
250  auto geometry = Geometry::MakeRect(Rect::MakeXYWH(100, 100, 100, 100));
251  auto transform = Matrix::MakeScale({2.0, 2.0, 2.0});
252 
253  ASSERT_RECT_NEAR(geometry->GetCoverage(transform).value(),
254  Rect::MakeXYWH(200, 200, 200, 200));
255 }

References ASSERT_RECT_NEAR, impeller::Geometry::MakeRect(), impeller::Matrix::MakeScale(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST_P() [306/384]

impeller::testing::TEST_P ( EntityTest  ,
InheritOpacityTest   
)

Definition at line 2178 of file entity_unittests.cc.

2178  {
2179  Entity entity;
2180 
2181  // Texture contents can always accept opacity.
2182  auto texture_contents = std::make_shared<TextureContents>();
2183  texture_contents->SetOpacity(0.5);
2184  ASSERT_TRUE(texture_contents->CanInheritOpacity(entity));
2185 
2186  texture_contents->SetInheritedOpacity(0.5);
2187  ASSERT_EQ(texture_contents->GetOpacity(), 0.25);
2188  texture_contents->SetInheritedOpacity(0.5);
2189  ASSERT_EQ(texture_contents->GetOpacity(), 0.25);
2190 
2191  // Solid color contents can accept opacity if their geometry
2192  // doesn't overlap.
2193  auto solid_color = std::make_shared<SolidColorContents>();
2194  solid_color->SetGeometry(
2195  Geometry::MakeRect(Rect::MakeLTRB(100, 100, 200, 200)));
2196  solid_color->SetColor(Color::Blue().WithAlpha(0.5));
2197 
2198  ASSERT_TRUE(solid_color->CanInheritOpacity(entity));
2199 
2200  solid_color->SetInheritedOpacity(0.5);
2201  ASSERT_EQ(solid_color->GetColor().alpha, 0.25);
2202  solid_color->SetInheritedOpacity(0.5);
2203  ASSERT_EQ(solid_color->GetColor().alpha, 0.25);
2204 
2205  // Color source contents can accept opacity if their geometry
2206  // doesn't overlap.
2207  auto tiled_texture = std::make_shared<TiledTextureContents>();
2208  tiled_texture->SetGeometry(
2209  Geometry::MakeRect(Rect::MakeLTRB(100, 100, 200, 200)));
2210  tiled_texture->SetOpacityFactor(0.5);
2211 
2212  ASSERT_TRUE(tiled_texture->CanInheritOpacity(entity));
2213 
2214  tiled_texture->SetInheritedOpacity(0.5);
2215  ASSERT_EQ(tiled_texture->GetOpacityFactor(), 0.25);
2216  tiled_texture->SetInheritedOpacity(0.5);
2217  ASSERT_EQ(tiled_texture->GetOpacityFactor(), 0.25);
2218 
2219  // Text contents can accept opacity if the text frames do not
2220  // overlap
2221  SkFont font = flutter::testing::CreateTestFontOfSize(30);
2222  auto blob = SkTextBlob::MakeFromString("A", font);
2223  auto frame = MakeTextFrameFromTextBlobSkia(blob);
2224  auto lazy_glyph_atlas =
2225  std::make_shared<LazyGlyphAtlas>(TypographerContextSkia::Make());
2226  lazy_glyph_atlas->AddTextFrame(*frame, 1.0f);
2227 
2228  auto text_contents = std::make_shared<TextContents>();
2229  text_contents->SetTextFrame(frame);
2230  text_contents->SetColor(Color::Blue().WithAlpha(0.5));
2231 
2232  ASSERT_TRUE(text_contents->CanInheritOpacity(entity));
2233 
2234  text_contents->SetInheritedOpacity(0.5);
2235  ASSERT_EQ(text_contents->GetColor().alpha, 0.25);
2236  text_contents->SetInheritedOpacity(0.5);
2237  ASSERT_EQ(text_contents->GetColor().alpha, 0.25);
2238 
2239  // Clips and restores trivially accept opacity.
2240  ASSERT_TRUE(ClipContents().CanInheritOpacity(entity));
2241  ASSERT_TRUE(ClipRestoreContents().CanInheritOpacity(entity));
2242 
2243  // Runtime effect contents can't accept opacity.
2244  auto runtime_effect = std::make_shared<RuntimeEffectContents>();
2245  ASSERT_FALSE(runtime_effect->CanInheritOpacity(entity));
2246 }

References impeller::Color::Blue(), impeller::TypographerContextSkia::Make(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Geometry::MakeRect(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [307/384]

impeller::testing::TEST_P ( EntityTest  ,
LinearGradientContentsIsOpaque   
)

Definition at line 2360 of file entity_unittests.cc.

2360  {
2361  LinearGradientContents contents;
2362  contents.SetColors({Color::CornflowerBlue()});
2363  ASSERT_TRUE(contents.IsOpaque());
2364  contents.SetColors({Color::CornflowerBlue().WithAlpha(0.5)});
2365  ASSERT_FALSE(contents.IsOpaque());
2366  contents.SetColors({Color::CornflowerBlue()});
2367  contents.SetTileMode(Entity::TileMode::kDecal);
2368  ASSERT_FALSE(contents.IsOpaque());
2369 }

References impeller::Color::CornflowerBlue(), impeller::LinearGradientContents::IsOpaque(), impeller::Entity::kDecal, impeller::LinearGradientContents::SetColors(), impeller::LinearGradientContents::SetTileMode(), and impeller::Color::WithAlpha().

◆ TEST_P() [308/384]

impeller::testing::TEST_P ( EntityTest  ,
LinearToSrgbFilter   
)

Definition at line 1887 of file entity_unittests.cc.

1887  {
1888  auto image = CreateTextureForFixture("kalimba.jpg");
1889  ASSERT_TRUE(image);
1890 
1891  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1892  auto filtered =
1893  ColorFilterContents::MakeLinearToSrgbFilter(FilterInput::Make(image));
1894 
1895  // Define the entity that will serve as the control image as a Gaussian blur
1896  // filter with no filter at all.
1897  Entity entity_left;
1898  entity_left.SetTransform(Matrix::MakeScale(GetContentScale()) *
1899  Matrix::MakeTranslation({100, 300}) *
1900  Matrix::MakeScale(Vector2{0.5, 0.5}));
1901  auto unfiltered = FilterContents::MakeGaussianBlur(FilterInput::Make(image),
1902  Sigma{0}, Sigma{0});
1903  entity_left.SetContents(unfiltered);
1904 
1905  // Define the entity that will be filtered from linear to sRGB.
1906  Entity entity_right;
1907  entity_right.SetTransform(Matrix::MakeScale(GetContentScale()) *
1908  Matrix::MakeTranslation({500, 300}) *
1909  Matrix::MakeScale(Vector2{0.5, 0.5}));
1910  entity_right.SetContents(filtered);
1911  return entity_left.Render(context, pass) &&
1912  entity_right.Render(context, pass);
1913  };
1914 
1915  ASSERT_TRUE(OpenPlaygroundHere(callback));
1916 }

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() [309/384]

impeller::testing::TEST_P ( EntityTest  ,
LinearToSrgbFilterCoverageIsCorrect   
)

Definition at line 1866 of file entity_unittests.cc.

1866  {
1867  // Set up a simple color background.
1868  auto fill = std::make_shared<SolidColorContents>();
1869  fill->SetGeometry(Geometry::MakeFillPath(
1870  PathBuilder{}.AddRect(Rect::MakeXYWH(0, 0, 300, 400)).TakePath()));
1871  fill->SetColor(Color::MintCream());
1872 
1873  auto filter =
1874  ColorFilterContents::MakeLinearToSrgbFilter(FilterInput::Make(fill));
1875 
1876  Entity e;
1877  e.SetTransform(Matrix());
1878 
1879  // Confirm that the actual filter coverage matches the expected coverage.
1880  auto actual = filter->GetCoverage(e);
1881  auto expected = Rect::MakeXYWH(0, 0, 300, 400);
1882 
1883  ASSERT_TRUE(actual.has_value());
1884  ASSERT_RECT_NEAR(actual.value(), expected);
1885 }

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() [310/384]

impeller::testing::TEST_P ( EntityTest  ,
MorphologyFilter   
)

Definition at line 1167 of file entity_unittests.cc.

1167  {
1168  auto boston = CreateTextureForFixture("boston.jpg");
1169  ASSERT_TRUE(boston);
1170 
1171  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1172  const char* morphology_type_names[] = {"Dilate", "Erode"};
1173  const FilterContents::MorphType morphology_types[] = {
1174  FilterContents::MorphType::kDilate, FilterContents::MorphType::kErode};
1175  static Color input_color = Color::Black();
1176  // UI state.
1177  static int selected_morphology_type = 0;
1178  static float radius[2] = {20, 20};
1179  static Color cover_color(1, 0, 0, 0.2);
1180  static Color bounds_color(0, 1, 0, 0.1);
1181  static float offset[2] = {500, 400};
1182  static float rotation = 0;
1183  static float scale[2] = {0.65, 0.65};
1184  static float skew[2] = {0, 0};
1185  static float path_rect[4] = {0, 0,
1186  static_cast<float>(boston->GetSize().width),
1187  static_cast<float>(boston->GetSize().height)};
1188  static float effect_transform_scale = 1;
1189 
1190  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1191  {
1192  ImGui::Combo("Morphology type", &selected_morphology_type,
1193  morphology_type_names,
1194  sizeof(morphology_type_names) / sizeof(char*));
1195  ImGui::SliderFloat2("Radius", radius, 0, 200);
1196  ImGui::SliderFloat("Input opacity", &input_color.alpha, 0, 1);
1197  ImGui::ColorEdit4("Cover color", reinterpret_cast<float*>(&cover_color));
1198  ImGui::ColorEdit4("Bounds color",
1199  reinterpret_cast<float*>(&bounds_color));
1200  ImGui::SliderFloat2("Translation", offset, 0,
1201  pass.GetRenderTargetSize().width);
1202  ImGui::SliderFloat("Rotation", &rotation, 0, kPi * 2);
1203  ImGui::SliderFloat2("Scale", scale, 0, 3);
1204  ImGui::SliderFloat2("Skew", skew, -3, 3);
1205  ImGui::SliderFloat4("Path XYWH", path_rect, -1000, 1000);
1206  ImGui::SliderFloat("Effect transform scale", &effect_transform_scale, 0,
1207  3);
1208  }
1209  ImGui::End();
1210 
1211  std::shared_ptr<Contents> input;
1212  Size input_size;
1213 
1214  auto input_rect =
1215  Rect::MakeXYWH(path_rect[0], path_rect[1], path_rect[2], path_rect[3]);
1216  auto texture = std::make_shared<TextureContents>();
1217  texture->SetSourceRect(Rect::MakeSize(boston->GetSize()));
1218  texture->SetDestinationRect(input_rect);
1219  texture->SetTexture(boston);
1220  texture->SetOpacity(input_color.alpha);
1221 
1222  input = texture;
1223  input_size = input_rect.GetSize();
1224 
1225  auto contents = FilterContents::MakeMorphology(
1226  FilterInput::Make(input), Radius{radius[0]}, Radius{radius[1]},
1227  morphology_types[selected_morphology_type]);
1228  contents->SetEffectTransform(Matrix::MakeScale(
1229  Vector2{effect_transform_scale, effect_transform_scale}));
1230 
1231  auto ctm = Matrix::MakeScale(GetContentScale()) *
1232  Matrix::MakeTranslation(Vector3(offset[0], offset[1])) *
1233  Matrix::MakeRotationZ(Radians(rotation)) *
1234  Matrix::MakeScale(Vector2(scale[0], scale[1])) *
1235  Matrix::MakeSkew(skew[0], skew[1]) *
1236  Matrix::MakeTranslation(-Point(input_size) / 2);
1237 
1238  Entity entity;
1239  entity.SetContents(contents);
1240  entity.SetTransform(ctm);
1241 
1242  entity.Render(context, pass);
1243 
1244  // Renders a red "cover" rectangle that shows the original position of the
1245  // unfiltered input.
1246  Entity cover_entity;
1247  cover_entity.SetContents(SolidColorContents::Make(
1248  PathBuilder{}.AddRect(input_rect).TakePath(), cover_color));
1249  cover_entity.SetTransform(ctm);
1250 
1251  cover_entity.Render(context, pass);
1252 
1253  // Renders a green bounding rect of the target filter.
1254  Entity bounds_entity;
1255  bounds_entity.SetContents(SolidColorContents::Make(
1256  PathBuilder{}.AddRect(contents->GetCoverage(entity).value()).TakePath(),
1257  bounds_color));
1258  bounds_entity.SetTransform(Matrix());
1259 
1260  bounds_entity.Render(context, pass);
1261 
1262  return true;
1263  };
1264  ASSERT_TRUE(OpenPlaygroundHere(callback));
1265 }

References impeller::PathBuilder::AddRect(), impeller::Color::alpha, impeller::Color::Black(), impeller::FilterContents::kDilate, impeller::FilterContents::kErode, impeller::kPi, impeller::SolidColorContents::Make(), impeller::FilterInput::Make(), impeller::FilterContents::MakeMorphology(), impeller::Matrix::MakeRotationZ(), impeller::Matrix::MakeScale(), impeller::TRect< Scalar >::MakeSize(), impeller::Matrix::MakeSkew(), impeller::Matrix::MakeTranslation(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Entity::Render(), impeller::Entity::SetContents(), impeller::Entity::SetTransform(), and impeller::PathBuilder::TakePath().

◆ TEST_P() [311/384]

impeller::testing::TEST_P ( EntityTest  ,
PipelineDescriptorEqAndHash   
)

Definition at line 2592 of file entity_unittests.cc.

2592  {
2593  auto desc_1 = std::make_shared<PipelineDescriptor>();
2594  auto desc_2 = std::make_shared<PipelineDescriptor>();
2595 
2596  EXPECT_TRUE(desc_1->IsEqual(*desc_2));
2597  EXPECT_EQ(desc_1->GetHash(), desc_2->GetHash());
2598 
2599  desc_1->SetUseSubpassInput(UseSubpassInput::kYes);
2600 
2601  EXPECT_FALSE(desc_1->IsEqual(*desc_2));
2602  EXPECT_NE(desc_1->GetHash(), desc_2->GetHash());
2603 
2604  desc_2->SetUseSubpassInput(UseSubpassInput::kYes);
2605 
2606  EXPECT_TRUE(desc_1->IsEqual(*desc_2));
2607  EXPECT_EQ(desc_1->GetHash(), desc_2->GetHash());
2608 }

References impeller::kYes.

◆ TEST_P() [312/384]

impeller::testing::TEST_P ( EntityTest  ,
PointFieldCanUseCompute   
)

Definition at line 2429 of file entity_unittests.cc.

2429  {
2430  EXPECT_EQ(PointFieldGeometry::CanUseCompute(*GetContentContext()),
2431  GetContext()->GetBackendType() == Context::BackendType::kMetal);
2432 }

References impeller::PointFieldGeometry::CanUseCompute(), and impeller::Context::kMetal.

◆ TEST_P() [313/384]

impeller::testing::TEST_P ( EntityTest  ,
PointFieldGeometryCoverage   
)

Definition at line 2421 of file entity_unittests.cc.

2421  {
2422  std::vector<Point> points = {{10, 20}, {100, 200}};
2423  auto geometry = Geometry::MakePointField(points, 5.0, false);
2424  ASSERT_EQ(*geometry->GetCoverage(Matrix()), Rect::MakeLTRB(5, 15, 105, 205));
2425  ASSERT_EQ(*geometry->GetCoverage(Matrix::MakeTranslation({30, 0, 0})),
2426  Rect::MakeLTRB(35, 15, 135, 205));
2427 }

References impeller::TRect< Scalar >::MakeLTRB(), impeller::Geometry::MakePointField(), and impeller::Matrix::MakeTranslation().

◆ TEST_P() [314/384]

impeller::testing::TEST_P ( EntityTest  ,
PointFieldGeometryDivisions   
)

Definition at line 2403 of file entity_unittests.cc.

2403  {
2404  // Square always gives 4 divisions.
2405  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(24.0, false), 4u);
2406  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(2.0, false), 4u);
2407  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(200.0, false), 4u);
2408 
2409  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(0.5, true), 4u);
2410  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(1.5, true), 8u);
2411  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(5.5, true), 24u);
2412  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(12.5, true), 34u);
2413  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(22.3, true), 22u);
2414  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(40.5, true), 40u);
2415  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(100.0, true), 100u);
2416  // Caps at 140.
2417  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(1000.0, true), 140u);
2418  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(20000.0, true), 140u);
2419 }

References impeller::PointFieldGeometry::ComputeCircleDivisions().

◆ TEST_P() [315/384]

impeller::testing::TEST_P ( EntityTest  ,
RadialGradientContentsIsOpaque   
)

Definition at line 2371 of file entity_unittests.cc.

2371  {
2372  RadialGradientContents contents;
2373  contents.SetColors({Color::CornflowerBlue()});
2374  ASSERT_TRUE(contents.IsOpaque());
2375  contents.SetColors({Color::CornflowerBlue().WithAlpha(0.5)});
2376  ASSERT_FALSE(contents.IsOpaque());
2377  contents.SetColors({Color::CornflowerBlue()});
2378  contents.SetTileMode(Entity::TileMode::kDecal);
2379  ASSERT_FALSE(contents.IsOpaque());
2380 }

References impeller::Color::CornflowerBlue(), impeller::RadialGradientContents::IsOpaque(), impeller::Entity::kDecal, impeller::RadialGradientContents::SetColors(), impeller::RadialGradientContents::SetTileMode(), and impeller::Color::WithAlpha().

◆ TEST_P() [316/384]

impeller::testing::TEST_P ( EntityTest  ,
RendersDstPerColorWithAlpha   
)

Definition at line 43 of file vertices_contents_unittests.cc.

43  {
44  using FS = GeometryColorPipeline::FragmentShader;
45 
46  auto contents = std::make_shared<VerticesContents>();
47  auto vertices = CreateColorVertices(
48  {{0, 0}, {100, 0}, {0, 100}, {100, 0}, {0, 100}, {100, 100}},
49  {Color::Red(), Color::Red(), Color::Red(), Color::Red(), Color::Red(),
50  Color::Red()});
51  auto src_contents = SolidColorContents::Make(
52  PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 100, 100)).TakePath(),
53  Color::Red());
54 
55  contents->SetGeometry(vertices);
56  contents->SetAlpha(0.5);
57  contents->SetBlendMode(BlendMode::kDestination);
58  contents->SetSourceContents(std::move(src_contents));
59 
60  auto content_context = GetContentContext();
61  auto buffer = content_context->GetContext()->CreateCommandBuffer();
62  auto render_target = RenderTarget::CreateOffscreenMSAA(
63  *content_context->GetContext(),
64  *GetContentContext()->GetRenderTargetCache(), {100, 100});
65  auto render_pass = buffer->CreateRenderPass(render_target);
66  Entity entity;
67 
68  ASSERT_TRUE(render_pass->GetCommands().empty());
69  ASSERT_TRUE(contents->Render(*content_context, entity, *render_pass));
70 
71  const auto& cmd = render_pass->GetCommands()[0];
72  auto* frag_uniforms = GetFragInfo<FS>(cmd);
73 
74  ASSERT_EQ(frag_uniforms->alpha, 0.5);
75 }

References impeller::PathBuilder::AddRect(), CreateColorVertices(), impeller::RenderTarget::CreateOffscreenMSAA(), impeller::kDestination, impeller::SolidColorContents::Make(), impeller::TRect< Scalar >::MakeLTRB(), and impeller::Color::Red().

◆ TEST_P() [317/384]

impeller::testing::TEST_P ( EntityTest  ,
RRectShadowTest   
)

Definition at line 1729 of file entity_unittests.cc.

1729  {
1730  auto callback = [&](ContentContext& context, RenderPass& pass) {
1731  static Color color = Color::Red();
1732  static float corner_radius = 100;
1733  static float blur_radius = 100;
1734  static bool show_coverage = false;
1735  static Color coverage_color = Color::Green().WithAlpha(0.2);
1736 
1737  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1738  ImGui::SliderFloat("Corner radius", &corner_radius, 0, 300);
1739  ImGui::SliderFloat("Blur radius", &blur_radius, 0, 300);
1740  ImGui::ColorEdit4("Color", reinterpret_cast<Scalar*>(&color));
1741  ImGui::Checkbox("Show coverage", &show_coverage);
1742  if (show_coverage) {
1743  ImGui::ColorEdit4("Coverage color",
1744  reinterpret_cast<Scalar*>(&coverage_color));
1745  }
1746  ImGui::End();
1747 
1748  auto [top_left, bottom_right] = IMPELLER_PLAYGROUND_LINE(
1749  Point(200, 200), Point(600, 400), 30, Color::White(), Color::White());
1750  auto rect =
1751  Rect::MakeLTRB(top_left.x, top_left.y, bottom_right.x, bottom_right.y);
1752 
1753  auto contents = std::make_unique<SolidRRectBlurContents>();
1754  contents->SetRRect(rect, {corner_radius, corner_radius});
1755  contents->SetColor(color);
1756  contents->SetSigma(Radius(blur_radius));
1757 
1758  Entity entity;
1759  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
1760  entity.SetContents(std::move(contents));
1761  entity.Render(context, pass);
1762 
1763  auto coverage = entity.GetCoverage();
1764  if (show_coverage && coverage.has_value()) {
1765  auto bounds_contents = std::make_unique<SolidColorContents>();
1766  bounds_contents->SetGeometry(Geometry::MakeFillPath(
1767  PathBuilder{}.AddRect(entity.GetCoverage().value()).TakePath()));
1768  bounds_contents->SetColor(coverage_color.Premultiply());
1769  Entity bounds_entity;
1770  bounds_entity.SetContents(std::move(bounds_contents));
1771  bounds_entity.Render(context, pass);
1772  }
1773 
1774  return true;
1775  };
1776  ASSERT_TRUE(OpenPlaygroundHere(callback));
1777 }

References impeller::PathBuilder::AddRect(), impeller::Entity::GetCoverage(), impeller::Color::Green(), IMPELLER_PLAYGROUND_LINE, impeller::Geometry::MakeFillPath(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeScale(), impeller::Color::Premultiply(), impeller::Color::Red(), impeller::Entity::Render(), impeller::Entity::SetContents(), impeller::Entity::SetTransform(), impeller::PathBuilder::TakePath(), impeller::Color::White(), and impeller::Color::WithAlpha().

◆ TEST_P() [318/384]

impeller::testing::TEST_P ( EntityTest  ,
RuntimeEffect   
)

Definition at line 2134 of file entity_unittests.cc.

2134  {
2135  if (!BackendSupportsFragmentProgram()) {
2136  GTEST_SKIP_("This backend doesn't support runtime effects.");
2137  }
2138 
2139  auto runtime_stages =
2140  OpenAssetAsRuntimeStage("runtime_stage_example.frag.iplr");
2141  auto runtime_stage =
2142  runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
2143  ASSERT_TRUE(runtime_stage);
2144  ASSERT_TRUE(runtime_stage->IsDirty());
2145 
2146  bool first_frame = true;
2147  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
2148  if (first_frame) {
2149  first_frame = false;
2150  } else {
2151  assert(runtime_stage->IsDirty() == false);
2152  }
2153 
2154  auto contents = std::make_shared<RuntimeEffectContents>();
2155  contents->SetGeometry(Geometry::MakeCover());
2156 
2157  contents->SetRuntimeStage(runtime_stage);
2158 
2159  struct FragUniforms {
2160  Vector2 iResolution;
2161  Scalar iTime;
2162  } frag_uniforms = {
2163  .iResolution = Vector2(GetWindowSize().width, GetWindowSize().height),
2164  .iTime = static_cast<Scalar>(GetSecondsElapsed()),
2165  };
2166  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
2167  uniform_data->resize(sizeof(FragUniforms));
2168  memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
2169  contents->SetUniformData(uniform_data);
2170 
2171  Entity entity;
2172  entity.SetContents(contents);
2173  return contents->Render(context, entity, pass);
2174  };
2175  ASSERT_TRUE(OpenPlaygroundHere(callback));
2176 }

References impeller::Geometry::MakeCover(), impeller::PlaygroundBackendToRuntimeStageBackend(), and impeller::Entity::SetContents().

◆ TEST_P() [319/384]

impeller::testing::TEST_P ( EntityTest  ,
SetBlendMode   
)

Definition at line 1267 of file entity_unittests.cc.

1267  {
1268  Entity entity;
1269  ASSERT_EQ(entity.GetBlendMode(), BlendMode::kSourceOver);
1270  entity.SetBlendMode(BlendMode::kClear);
1271  ASSERT_EQ(entity.GetBlendMode(), BlendMode::kClear);
1272 }

References impeller::Entity::GetBlendMode(), impeller::kClear, impeller::kSourceOver, and impeller::Entity::SetBlendMode().

◆ TEST_P() [320/384]

impeller::testing::TEST_P ( EntityTest  ,
SolidColorContentsIsOpaque   
)

Definition at line 2344 of file entity_unittests.cc.

2344  {
2345  SolidColorContents contents;
2346  contents.SetColor(Color::CornflowerBlue());
2347  ASSERT_TRUE(contents.IsOpaque());
2348  contents.SetColor(Color::CornflowerBlue().WithAlpha(0.5));
2349  ASSERT_FALSE(contents.IsOpaque());
2350 }

References impeller::Color::CornflowerBlue(), impeller::SolidColorContents::IsOpaque(), and impeller::SolidColorContents::SetColor().

◆ TEST_P() [321/384]

impeller::testing::TEST_P ( EntityTest  ,
SolidColorContentsStrokeSetMiterLimit   
)

Definition at line 779 of file entity_unittests.cc.

779  {
780  {
781  auto geometry = Geometry::MakeStrokePath(Path{});
782  auto path_geometry = static_cast<StrokePathGeometry*>(geometry.get());
783  ASSERT_FLOAT_EQ(path_geometry->GetMiterLimit(), 4);
784  }
785 
786  {
787  auto geometry = Geometry::MakeStrokePath(Path{}, 1.0, /*miter_limit=*/8.0);
788  auto path_geometry = static_cast<StrokePathGeometry*>(geometry.get());
789  ASSERT_FLOAT_EQ(path_geometry->GetMiterLimit(), 8);
790  }
791 
792  {
793  auto geometry = Geometry::MakeStrokePath(Path{}, 1.0, /*miter_limit=*/-1.0);
794  auto path_geometry = static_cast<StrokePathGeometry*>(geometry.get());
795  ASSERT_FLOAT_EQ(path_geometry->GetMiterLimit(), 4);
796  }
797 }

References impeller::Geometry::MakeStrokePath().

◆ TEST_P() [322/384]

impeller::testing::TEST_P ( EntityTest  ,
SolidColorContentsStrokeSetStrokeCapsAndJoins   
)

Definition at line 757 of file entity_unittests.cc.

757  {
758  {
759  auto geometry = Geometry::MakeStrokePath(Path{});
760  auto path_geometry = static_cast<StrokePathGeometry*>(geometry.get());
761  // Defaults.
762  ASSERT_EQ(path_geometry->GetStrokeCap(), Cap::kButt);
763  ASSERT_EQ(path_geometry->GetStrokeJoin(), Join::kMiter);
764  }
765 
766  {
767  auto geometry = Geometry::MakeStrokePath(Path{}, 1.0, 4.0, Cap::kSquare);
768  auto path_geometry = static_cast<StrokePathGeometry*>(geometry.get());
769  ASSERT_EQ(path_geometry->GetStrokeCap(), Cap::kSquare);
770  }
771 
772  {
773  auto geometry = Geometry::MakeStrokePath(Path{}, 1.0, 4.0, Cap::kRound);
774  auto path_geometry = static_cast<StrokePathGeometry*>(geometry.get());
775  ASSERT_EQ(path_geometry->GetStrokeCap(), Cap::kRound);
776  }
777 }

References impeller::kButt, impeller::kMiter, impeller::kRound, impeller::kSquare, and impeller::Geometry::MakeStrokePath().

◆ TEST_P() [323/384]

impeller::testing::TEST_P ( EntityTest  ,
SolidFillCoverageIsCorrect   
)

Definition at line 1556 of file entity_unittests.cc.

1556  {
1557  // No transform
1558  {
1559  auto fill = std::make_shared<SolidColorContents>();
1560  fill->SetColor(Color::CornflowerBlue());
1561  auto expected = Rect::MakeLTRB(100, 110, 200, 220);
1562  fill->SetGeometry(
1563  Geometry::MakeFillPath(PathBuilder{}.AddRect(expected).TakePath()));
1564 
1565  auto coverage = fill->GetCoverage({});
1566  ASSERT_TRUE(coverage.has_value());
1567  ASSERT_RECT_NEAR(coverage.value(), expected);
1568  }
1569 
1570  // Entity transform
1571  {
1572  auto fill = std::make_shared<SolidColorContents>();
1573  fill->SetColor(Color::CornflowerBlue());
1574  fill->SetGeometry(Geometry::MakeFillPath(
1575  PathBuilder{}.AddRect(Rect::MakeLTRB(100, 110, 200, 220)).TakePath()));
1576 
1577  Entity entity;
1578  entity.SetTransform(Matrix::MakeTranslation(Vector2(4, 5)));
1579  entity.SetContents(std::move(fill));
1580 
1581  auto coverage = entity.GetCoverage();
1582  auto expected = Rect::MakeLTRB(104, 115, 204, 225);
1583  ASSERT_TRUE(coverage.has_value());
1584  ASSERT_RECT_NEAR(coverage.value(), expected);
1585  }
1586 
1587  // No coverage for fully transparent colors
1588  {
1589  auto fill = std::make_shared<SolidColorContents>();
1590  fill->SetColor(Color::WhiteTransparent());
1591  fill->SetGeometry(Geometry::MakeFillPath(
1592  PathBuilder{}.AddRect(Rect::MakeLTRB(100, 110, 200, 220)).TakePath()));
1593 
1594  auto coverage = fill->GetCoverage({});
1595  ASSERT_FALSE(coverage.has_value());
1596  }
1597 }

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() [324/384]

impeller::testing::TEST_P ( EntityTest  ,
SolidFillShouldRenderIsCorrect   
)

Definition at line 1599 of file entity_unittests.cc.

1599  {
1600  // No path.
1601  {
1602  auto fill = std::make_shared<SolidColorContents>();
1603  fill->SetColor(Color::CornflowerBlue());
1604  ASSERT_FALSE(fill->ShouldRender(Entity{}, Rect::MakeSize(Size{100, 100})));
1605  ASSERT_FALSE(
1606  fill->ShouldRender(Entity{}, Rect::MakeLTRB(-100, -100, -50, -50)));
1607  }
1608 
1609  // With path.
1610  {
1611  auto fill = std::make_shared<SolidColorContents>();
1612  fill->SetColor(Color::CornflowerBlue());
1613  fill->SetGeometry(Geometry::MakeFillPath(
1614  PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 100, 100)).TakePath()));
1615  ASSERT_TRUE(fill->ShouldRender(Entity{}, Rect::MakeSize(Size{100, 100})));
1616  ASSERT_FALSE(
1617  fill->ShouldRender(Entity{}, Rect::MakeLTRB(-100, -100, -50, -50)));
1618  }
1619 
1620  // With paint cover.
1621  {
1622  auto fill = std::make_shared<SolidColorContents>();
1623  fill->SetColor(Color::CornflowerBlue());
1624  fill->SetGeometry(Geometry::MakeCover());
1625  ASSERT_TRUE(fill->ShouldRender(Entity{}, Rect::MakeSize(Size{100, 100})));
1626  ASSERT_TRUE(
1627  fill->ShouldRender(Entity{}, Rect::MakeLTRB(-100, -100, -50, -50)));
1628  }
1629 }

References impeller::PathBuilder::AddRect(), impeller::Color::CornflowerBlue(), impeller::Geometry::MakeCover(), impeller::Geometry::MakeFillPath(), impeller::TRect< Scalar >::MakeLTRB(), and impeller::TRect< Scalar >::MakeSize().

◆ TEST_P() [325/384]

impeller::testing::TEST_P ( EntityTest  ,
SolidStrokeCoverageIsCorrect   
)

Definition at line 1280 of file entity_unittests.cc.

1280  {
1281  {
1282  auto geometry = Geometry::MakeStrokePath(
1283  PathBuilder{}.AddLine({0, 0}, {10, 10}).TakePath(), 4.0, 4.0,
1284  Cap::kButt, Join::kBevel);
1285 
1286  Entity entity;
1287  auto contents = std::make_unique<SolidColorContents>();
1288  contents->SetGeometry(std::move(geometry));
1289  contents->SetColor(Color::Black());
1290  entity.SetContents(std::move(contents));
1291  auto actual = entity.GetCoverage();
1292  auto expected = Rect::MakeLTRB(-2, -2, 12, 12);
1293  ASSERT_TRUE(actual.has_value());
1294  ASSERT_RECT_NEAR(actual.value(), expected);
1295  }
1296 
1297  // Cover the Cap::kSquare case.
1298  {
1299  auto geometry = Geometry::MakeStrokePath(
1300  PathBuilder{}.AddLine({0, 0}, {10, 10}).TakePath(), 4.0, 4.0,
1301  Cap::kSquare, Join::kBevel);
1302 
1303  Entity entity;
1304  auto contents = std::make_unique<SolidColorContents>();
1305  contents->SetGeometry(std::move(geometry));
1306  contents->SetColor(Color::Black());
1307  entity.SetContents(std::move(contents));
1308  auto actual = entity.GetCoverage();
1309  auto expected =
1310  Rect::MakeLTRB(-sqrt(8), -sqrt(8), 10 + sqrt(8), 10 + sqrt(8));
1311  ASSERT_TRUE(actual.has_value());
1312  ASSERT_RECT_NEAR(actual.value(), expected);
1313  }
1314 
1315  // Cover the Join::kMiter case.
1316  {
1317  auto geometry = Geometry::MakeStrokePath(
1318  PathBuilder{}.AddLine({0, 0}, {10, 10}).TakePath(), 4.0, 2.0,
1319  Cap::kSquare, Join::kMiter);
1320 
1321  Entity entity;
1322  auto contents = std::make_unique<SolidColorContents>();
1323  contents->SetGeometry(std::move(geometry));
1324  contents->SetColor(Color::Black());
1325  entity.SetContents(std::move(contents));
1326  auto actual = entity.GetCoverage();
1327  auto expected = Rect::MakeLTRB(-4, -4, 14, 14);
1328  ASSERT_TRUE(actual.has_value());
1329  ASSERT_RECT_NEAR(actual.value(), expected);
1330  }
1331 }

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() [326/384]

impeller::testing::TEST_P ( EntityTest  ,
SpecializationConstantsAreAppliedToVariants   
)

Definition at line 2544 of file entity_unittests.cc.

2544  {
2545  auto content_context =
2546  ContentContext(GetContext(), TypographerContextSkia::Make());
2547 
2548  auto default_color_burn = content_context.GetBlendColorBurnPipeline(
2549  {.has_stencil_attachment = false});
2550  auto alt_color_burn = content_context.GetBlendColorBurnPipeline(
2551  {.has_stencil_attachment = true});
2552 
2553  ASSERT_NE(default_color_burn, alt_color_burn);
2554  ASSERT_EQ(default_color_burn->GetDescriptor().GetSpecializationConstants(),
2555  alt_color_burn->GetDescriptor().GetSpecializationConstants());
2556 
2557  auto decal_supported = static_cast<Scalar>(
2558  GetContext()->GetCapabilities()->SupportsDecalSamplerAddressMode());
2559  std::vector<Scalar> expected_constants = {5, decal_supported};
2560  ASSERT_EQ(default_color_burn->GetDescriptor().GetSpecializationConstants(),
2561  expected_constants);
2562 }

References impeller::TypographerContextSkia::Make().

◆ TEST_P() [327/384]

impeller::testing::TEST_P ( EntityTest  ,
SrgbToLinearFilter   
)

Definition at line 1939 of file entity_unittests.cc.

1939  {
1940  auto image = CreateTextureForFixture("embarcadero.jpg");
1941  ASSERT_TRUE(image);
1942 
1943  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1944  auto filtered =
1945  ColorFilterContents::MakeSrgbToLinearFilter(FilterInput::Make(image));
1946 
1947  // Define the entity that will serve as the control image as a Gaussian blur
1948  // filter with no filter at all.
1949  Entity entity_left;
1950  entity_left.SetTransform(Matrix::MakeScale(GetContentScale()) *
1951  Matrix::MakeTranslation({100, 300}) *
1952  Matrix::MakeScale(Vector2{0.5, 0.5}));
1953  auto unfiltered = FilterContents::MakeGaussianBlur(FilterInput::Make(image),
1954  Sigma{0}, Sigma{0});
1955  entity_left.SetContents(unfiltered);
1956 
1957  // Define the entity that will be filtered from sRGB to linear.
1958  Entity entity_right;
1959  entity_right.SetTransform(Matrix::MakeScale(GetContentScale()) *
1960  Matrix::MakeTranslation({500, 300}) *
1961  Matrix::MakeScale(Vector2{0.5, 0.5}));
1962  entity_right.SetContents(filtered);
1963  return entity_left.Render(context, pass) &&
1964  entity_right.Render(context, pass);
1965  };
1966 
1967  ASSERT_TRUE(OpenPlaygroundHere(callback));
1968 }

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() [328/384]

impeller::testing::TEST_P ( EntityTest  ,
SrgbToLinearFilterCoverageIsCorrect   
)

Definition at line 1918 of file entity_unittests.cc.

1918  {
1919  // Set up a simple color background.
1920  auto fill = std::make_shared<SolidColorContents>();
1921  fill->SetGeometry(Geometry::MakeFillPath(
1922  PathBuilder{}.AddRect(Rect::MakeXYWH(0, 0, 300, 400)).TakePath()));
1923  fill->SetColor(Color::DeepPink());
1924 
1925  auto filter =
1926  ColorFilterContents::MakeSrgbToLinearFilter(FilterInput::Make(fill));
1927 
1928  Entity e;
1929  e.SetTransform(Matrix());
1930 
1931  // Confirm that the actual filter coverage matches the expected coverage.
1932  auto actual = filter->GetCoverage(e);
1933  auto expected = Rect::MakeXYWH(0, 0, 300, 400);
1934 
1935  ASSERT_TRUE(actual.has_value());
1936  ASSERT_RECT_NEAR(actual.value(), expected);
1937 }

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() [329/384]

impeller::testing::TEST_P ( EntityTest  ,
StrokeCapAndJoinTest   
)

Definition at line 339 of file entity_unittests.cc.

339  {
340  const Point padding(300, 250);
341  const Point margin(140, 180);
342 
343  auto callback = [&](ContentContext& context, RenderPass& pass) {
344  // Slightly above sqrt(2) by default, so that right angles are just below
345  // the limit and acute angles are over the limit (causing them to get
346  // beveled).
347  static Scalar miter_limit = 1.41421357;
348  static Scalar width = 30;
349 
350  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
351  {
352  ImGui::SliderFloat("Miter limit", &miter_limit, 0, 30);
353  ImGui::SliderFloat("Stroke width", &width, 0, 100);
354  if (ImGui::Button("Reset")) {
355  miter_limit = 1.41421357;
356  width = 30;
357  }
358  }
359  ImGui::End();
360 
361  auto world_matrix = Matrix::MakeScale(GetContentScale());
362  auto render_path = [width = width, &context, &pass, &world_matrix](
363  const Path& path, Cap cap, Join join) {
364  auto contents = std::make_unique<SolidColorContents>();
365  contents->SetGeometry(Geometry::MakeStrokePath(path.Clone(), width,
366  miter_limit, cap, join));
367  contents->SetColor(Color::Red());
368 
369  Entity entity;
370  entity.SetTransform(world_matrix);
371  entity.SetContents(std::move(contents));
372 
373  auto coverage = entity.GetCoverage();
374  if (coverage.has_value()) {
375  auto bounds_contents = std::make_unique<SolidColorContents>();
376  bounds_contents->SetGeometry(Geometry::MakeFillPath(
377  PathBuilder{}.AddRect(entity.GetCoverage().value()).TakePath()));
378  bounds_contents->SetColor(Color::Green().WithAlpha(0.5));
379  Entity bounds_entity;
380  bounds_entity.SetContents(std::move(bounds_contents));
381  bounds_entity.Render(context, pass);
382  }
383 
384  entity.Render(context, pass);
385  };
386 
387  const Point a_def(0, 0), b_def(0, 100), c_def(150, 0), d_def(150, -100),
388  e_def(75, 75);
389  const Scalar r = 30;
390  // Cap::kButt demo.
391  {
392  Point off = Point(0, 0) * padding + margin;
393  auto [a, b] = IMPELLER_PLAYGROUND_LINE(off + a_def, off + b_def, r,
394  Color::Black(), Color::White());
395  auto [c, d] = IMPELLER_PLAYGROUND_LINE(off + c_def, off + d_def, r,
396  Color::Black(), Color::White());
397  render_path(PathBuilder{}.AddCubicCurve(a, b, d, c).TakePath(),
398  Cap::kButt, Join::kBevel);
399  }
400 
401  // Cap::kSquare demo.
402  {
403  Point off = Point(1, 0) * padding + margin;
404  auto [a, b] = IMPELLER_PLAYGROUND_LINE(off + a_def, off + b_def, r,
405  Color::Black(), Color::White());
406  auto [c, d] = IMPELLER_PLAYGROUND_LINE(off + c_def, off + d_def, r,
407  Color::Black(), Color::White());
408  render_path(PathBuilder{}.AddCubicCurve(a, b, d, c).TakePath(),
409  Cap::kSquare, Join::kBevel);
410  }
411 
412  // Cap::kRound demo.
413  {
414  Point off = Point(2, 0) * padding + margin;
415  auto [a, b] = IMPELLER_PLAYGROUND_LINE(off + a_def, off + b_def, r,
416  Color::Black(), Color::White());
417  auto [c, d] = IMPELLER_PLAYGROUND_LINE(off + c_def, off + d_def, r,
418  Color::Black(), Color::White());
419  render_path(PathBuilder{}.AddCubicCurve(a, b, d, c).TakePath(),
420  Cap::kRound, Join::kBevel);
421  }
422 
423  // Join::kBevel demo.
424  {
425  Point off = Point(0, 1) * padding + margin;
426  Point a = IMPELLER_PLAYGROUND_POINT(off + a_def, r, Color::White());
427  Point b = IMPELLER_PLAYGROUND_POINT(off + e_def, r, Color::White());
428  Point c = IMPELLER_PLAYGROUND_POINT(off + c_def, r, Color::White());
429  render_path(
430  PathBuilder{}.MoveTo(a).LineTo(b).LineTo(c).Close().TakePath(),
431  Cap::kButt, Join::kBevel);
432  }
433 
434  // Join::kMiter demo.
435  {
436  Point off = Point(1, 1) * padding + margin;
437  Point a = IMPELLER_PLAYGROUND_POINT(off + a_def, r, Color::White());
438  Point b = IMPELLER_PLAYGROUND_POINT(off + e_def, r, Color::White());
439  Point c = IMPELLER_PLAYGROUND_POINT(off + c_def, r, Color::White());
440  render_path(
441  PathBuilder{}.MoveTo(a).LineTo(b).LineTo(c).Close().TakePath(),
442  Cap::kButt, Join::kMiter);
443  }
444 
445  // Join::kRound demo.
446  {
447  Point off = Point(2, 1) * padding + margin;
448  Point a = IMPELLER_PLAYGROUND_POINT(off + a_def, r, Color::White());
449  Point b = IMPELLER_PLAYGROUND_POINT(off + e_def, r, Color::White());
450  Point c = IMPELLER_PLAYGROUND_POINT(off + c_def, r, Color::White());
451  render_path(
452  PathBuilder{}.MoveTo(a).LineTo(b).LineTo(c).Close().TakePath(),
453  Cap::kButt, Join::kRound);
454  }
455 
456  return true;
457  };
458  ASSERT_TRUE(OpenPlaygroundHere(callback));
459 }

References impeller::PathBuilder::AddCubicCurve(), impeller::PathBuilder::AddRect(), impeller::Color::Black(), impeller::Close(), impeller::Entity::GetCoverage(), impeller::Color::Green(), IMPELLER_PLAYGROUND_LINE, IMPELLER_PLAYGROUND_POINT, impeller::kBevel, impeller::kButt, impeller::kMiter, impeller::kRound, impeller::kSquare, impeller::LineTo(), impeller::Geometry::MakeFillPath(), impeller::Matrix::MakeScale(), impeller::Geometry::MakeStrokePath(), impeller::PathBuilder::MoveTo(), impeller::Color::Red(), impeller::Entity::Render(), impeller::Entity::SetContents(), impeller::Entity::SetTransform(), impeller::PathBuilder::TakePath(), and impeller::Color::White().

◆ TEST_P() [330/384]

impeller::testing::TEST_P ( EntityTest  ,
StrokeWithTextureContents   
)

Definition at line 276 of file entity_unittests.cc.

276  {
277  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
278  Path path = PathBuilder{}
279  .MoveTo({100, 100})
280  .LineTo({100, 200})
281  .MoveTo({100, 300})
282  .LineTo({100, 400})
283  .MoveTo({100, 500})
284  .LineTo({100, 600})
285  .TakePath();
286 
287  Entity entity;
288  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
289  auto contents = std::make_unique<TiledTextureContents>();
290  contents->SetGeometry(Geometry::MakeStrokePath(std::move(path), 100.0));
291  contents->SetTexture(bridge);
292  contents->SetTileModes(Entity::TileMode::kClamp, Entity::TileMode::kClamp);
293  entity.SetContents(std::move(contents));
294  ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
295 }

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() [331/384]

impeller::testing::TEST_P ( EntityTest  ,
SweepGradientContentsIsOpaque   
)

Definition at line 2382 of file entity_unittests.cc.

2382  {
2383  RadialGradientContents contents;
2384  contents.SetColors({Color::CornflowerBlue()});
2385  ASSERT_TRUE(contents.IsOpaque());
2386  contents.SetColors({Color::CornflowerBlue().WithAlpha(0.5)});
2387  ASSERT_FALSE(contents.IsOpaque());
2388  contents.SetColors({Color::CornflowerBlue()});
2389  contents.SetTileMode(Entity::TileMode::kDecal);
2390  ASSERT_FALSE(contents.IsOpaque());
2391 }

References impeller::Color::CornflowerBlue(), impeller::RadialGradientContents::IsOpaque(), impeller::Entity::kDecal, impeller::RadialGradientContents::SetColors(), impeller::RadialGradientContents::SetTileMode(), and impeller::Color::WithAlpha().

◆ TEST_P() [332/384]

impeller::testing::TEST_P ( EntityTest  ,
TextContentsCeilsGlyphScaleToDecimal   
)

Definition at line 2454 of file entity_unittests.cc.

2454  {
2455  ASSERT_EQ(TextFrame::RoundScaledFontSize(0.4321111f, 12), 0.43f);
2456  ASSERT_EQ(TextFrame::RoundScaledFontSize(0.5321111f, 12), 0.53f);
2457  ASSERT_EQ(TextFrame::RoundScaledFontSize(2.1f, 12), 2.1f);
2458  ASSERT_EQ(TextFrame::RoundScaledFontSize(0.0f, 12), 0.0f);
2459 }

References impeller::TextFrame::RoundScaledFontSize().

◆ TEST_P() [333/384]

impeller::testing::TEST_P ( EntityTest  ,
ThreeStrokesInOnePath   
)

Definition at line 257 of file entity_unittests.cc.

257  {
258  Path path = PathBuilder{}
259  .MoveTo({100, 100})
260  .LineTo({100, 200})
261  .MoveTo({100, 300})
262  .LineTo({100, 400})
263  .MoveTo({100, 500})
264  .LineTo({100, 600})
265  .TakePath();
266 
267  Entity entity;
268  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
269  auto contents = std::make_unique<SolidColorContents>();
270  contents->SetGeometry(Geometry::MakeStrokePath(std::move(path), 5.0));
271  contents->SetColor(Color::Red());
272  entity.SetContents(std::move(contents));
273  ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
274 }

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() [334/384]

impeller::testing::TEST_P ( EntityTest  ,
TiledTextureContentsIsOpaque   
)

Definition at line 2393 of file entity_unittests.cc.

2393  {
2394  auto bay_bridge = CreateTextureForFixture("bay_bridge.jpg");
2395  TiledTextureContents contents;
2396  contents.SetTexture(bay_bridge);
2397  // This is a placeholder test. Images currently never decompress as opaque
2398  // (whether in Flutter or the playground), and so this should currently always
2399  // return false in practice.
2400  ASSERT_FALSE(contents.IsOpaque());
2401 }

References impeller::TiledTextureContents::IsOpaque(), and impeller::TiledTextureContents::SetTexture().

◆ TEST_P() [335/384]

impeller::testing::TEST_P ( EntityTest  ,
TiledTextureContentsRendersWithCorrectPipeline   
)

Definition at line 19 of file tiled_texture_contents_unittests.cc.

19  {
20  TextureDescriptor texture_desc;
21  texture_desc.size = {100, 100};
22  texture_desc.type = TextureType::kTexture2D;
23  texture_desc.format = PixelFormat::kR8G8B8A8UNormInt;
24  texture_desc.storage_mode = StorageMode::kDevicePrivate;
25  auto texture =
26  GetContext()->GetResourceAllocator()->CreateTexture(texture_desc);
27 
28  TiledTextureContents contents;
29  contents.SetTexture(texture);
30  contents.SetGeometry(Geometry::MakeCover());
31 
32  auto content_context = GetContentContext();
33  auto buffer = content_context->GetContext()->CreateCommandBuffer();
34  auto render_target = RenderTarget::CreateOffscreenMSAA(
35  *content_context->GetContext(),
36  *GetContentContext()->GetRenderTargetCache(), {100, 100});
37  auto render_pass = buffer->CreateRenderPass(render_target);
38 
39  ASSERT_TRUE(contents.Render(*GetContentContext(), {}, *render_pass));
40  const std::vector<Command>& commands = render_pass->GetCommands();
41 
42  ASSERT_EQ(commands.size(), 1u);
43  ASSERT_STREQ(commands[0].pipeline->GetDescriptor().GetLabel().c_str(),
44  "TextureFill Pipeline V#1");
45 }

References impeller::RenderTarget::CreateOffscreenMSAA(), impeller::TextureDescriptor::format, impeller::kDevicePrivate, 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() [336/384]

impeller::testing::TEST_P ( EntityTest  ,
TiledTextureContentsRendersWithCorrectPipelineExternalOES   
)

Definition at line 49 of file tiled_texture_contents_unittests.cc.

49  {
50  if (GetParam() != PlaygroundBackend::kOpenGLES) {
51  GTEST_SKIP_(
52  "External OES textures are only valid for the OpenGLES backend.");
53  }
54 
55  TextureDescriptor texture_desc;
56  texture_desc.size = {100, 100};
57  texture_desc.type = TextureType::kTextureExternalOES;
58  texture_desc.format = PixelFormat::kR8G8B8A8UNormInt;
59  texture_desc.storage_mode = StorageMode::kDevicePrivate;
60  auto texture =
61  GetContext()->GetResourceAllocator()->CreateTexture(texture_desc);
62 
63  TiledTextureContents contents;
64  contents.SetTexture(texture);
65  contents.SetGeometry(Geometry::MakeCover());
66 
67  auto content_context = GetContentContext();
68  auto buffer = content_context->GetContext()->CreateCommandBuffer();
69  auto render_target = RenderTarget::CreateOffscreenMSAA(
70  *content_context->GetContext(),
71  *GetContentContext()->GetRenderTargetCache(), {100, 100});
72  auto render_pass = buffer->CreateRenderPass(render_target);
73 
74  ASSERT_TRUE(contents.Render(*GetContentContext(), {}, *render_pass));
75  const std::vector<Command>& commands = render_pass->GetCommands();
76 
77  ASSERT_EQ(commands.size(), 1u);
78  ASSERT_STREQ(commands[0].pipeline->GetDescriptor().GetLabel().c_str(),
79  "TextureFill Pipeline V#1");
80 }

References impeller::RenderTarget::CreateOffscreenMSAA(), 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() [337/384]

impeller::testing::TEST_P ( EntityTest  ,
TriangleInsideASquare   
)

Definition at line 297 of file entity_unittests.cc.

297  {
298  auto callback = [&](ContentContext& context, RenderPass& pass) {
299  Point offset(100, 100);
300 
301  Point a =
302  IMPELLER_PLAYGROUND_POINT(Point(10, 10) + offset, 20, Color::White());
303  Point b =
304  IMPELLER_PLAYGROUND_POINT(Point(210, 10) + offset, 20, Color::White());
305  Point c =
306  IMPELLER_PLAYGROUND_POINT(Point(210, 210) + offset, 20, Color::White());
307  Point d =
308  IMPELLER_PLAYGROUND_POINT(Point(10, 210) + offset, 20, Color::White());
309  Point e =
310  IMPELLER_PLAYGROUND_POINT(Point(50, 50) + offset, 20, Color::White());
311  Point f =
312  IMPELLER_PLAYGROUND_POINT(Point(100, 50) + offset, 20, Color::White());
313  Point g =
314  IMPELLER_PLAYGROUND_POINT(Point(50, 150) + offset, 20, Color::White());
315  Path path = PathBuilder{}
316  .MoveTo(a)
317  .LineTo(b)
318  .LineTo(c)
319  .LineTo(d)
320  .Close()
321  .MoveTo(e)
322  .LineTo(f)
323  .LineTo(g)
324  .Close()
325  .TakePath();
326 
327  Entity entity;
328  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
329  auto contents = std::make_unique<SolidColorContents>();
330  contents->SetGeometry(Geometry::MakeStrokePath(std::move(path), 20.0));
331  contents->SetColor(Color::Red());
332  entity.SetContents(std::move(contents));
333 
334  return entity.Render(context, pass);
335  };
336  ASSERT_TRUE(OpenPlaygroundHere(callback));
337 }

References impeller::PathBuilder::Close(), IMPELLER_PLAYGROUND_POINT, impeller::PathBuilder::LineTo(), impeller::Matrix::MakeScale(), impeller::Geometry::MakeStrokePath(), impeller::PathBuilder::MoveTo(), impeller::Color::Red(), impeller::Entity::Render(), impeller::Entity::SetContents(), impeller::Entity::SetTransform(), impeller::PathBuilder::TakePath(), and impeller::Color::White().

◆ TEST_P() [338/384]

impeller::testing::TEST_P ( EntityTest  ,
YUVToRGBFilter   
)

Definition at line 2101 of file entity_unittests.cc.

2101  {
2102  if (GetParam() == PlaygroundBackend::kOpenGLES) {
2103  // TODO(114588) : Support YUV to RGB filter on OpenGLES backend.
2104  GTEST_SKIP_("YUV to RGB filter is not supported on OpenGLES backend yet.");
2105  }
2106 
2107  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
2108  YUVColorSpace yuv_color_space_array[2]{YUVColorSpace::kBT601FullRange,
2109  YUVColorSpace::kBT601LimitedRange};
2110  for (int i = 0; i < 2; i++) {
2111  auto yuv_color_space = yuv_color_space_array[i];
2112  auto textures =
2113  CreateTestYUVTextures(GetContext().get(), yuv_color_space);
2114  auto filter_contents = FilterContents::MakeYUVToRGBFilter(
2115  textures[0], textures[1], yuv_color_space);
2116  Entity filter_entity;
2117  filter_entity.SetContents(filter_contents);
2118  auto snapshot = filter_contents->RenderToSnapshot(context, filter_entity);
2119 
2120  Entity entity;
2121  auto contents = TextureContents::MakeRect(Rect::MakeLTRB(0, 0, 256, 256));
2122  contents->SetTexture(snapshot->texture);
2123  contents->SetSourceRect(Rect::MakeSize(snapshot->texture->GetSize()));
2124  entity.SetContents(contents);
2125  entity.SetTransform(
2126  Matrix::MakeTranslation({static_cast<Scalar>(100 + 400 * i), 300}));
2127  entity.Render(context, pass);
2128  }
2129  return true;
2130  };
2131  ASSERT_TRUE(OpenPlaygroundHere(callback));
2132 }

References CreateTestYUVTextures(), impeller::kBT601FullRange, impeller::kBT601LimitedRange, impeller::kOpenGLES, impeller::TRect< Scalar >::MakeLTRB(), impeller::TextureContents::MakeRect(), impeller::TRect< Scalar >::MakeSize(), impeller::Matrix::MakeTranslation(), impeller::FilterContents::MakeYUVToRGBFilter(), impeller::Entity::Render(), impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [339/384]

impeller::testing::TEST_P ( GaussianBlurFilterContentsTest  ,
CalculateUVsSimple   
)

Definition at line 279 of file gaussian_blur_filter_contents_unittests.cc.

279  {
280  TextureDescriptor desc = {
281  .storage_mode = StorageMode::kDevicePrivate,
282  .format = PixelFormat::kB8G8R8A8UNormInt,
283  .size = ISize(100, 100),
284  };
285  std::shared_ptr<Texture> texture = MakeTexture(desc);
286  auto filter_input = FilterInput::Make(texture);
287  Entity entity;
288  Quad uvs = GaussianBlurFilterContents::CalculateUVs(
289  filter_input, entity, Rect::MakeSize(ISize(100, 100)), ISize(100, 100));
290  std::optional<Rect> uvs_bounds = Rect::MakePointBounds(uvs);
291  EXPECT_TRUE(uvs_bounds.has_value());
292  if (uvs_bounds.has_value()) {
293  EXPECT_TRUE(RectNear(uvs_bounds.value(), Rect::MakeXYWH(0, 0, 1, 1)));
294  }
295 }

References impeller::GaussianBlurFilterContents::CalculateUVs(), impeller::kB8G8R8A8UNormInt, impeller::kDevicePrivate, impeller::FilterInput::Make(), impeller::TRect< Scalar >::MakePointBounds(), impeller::TRect< Scalar >::MakeSize(), impeller::TRect< Scalar >::MakeXYWH(), RectNear(), and impeller::TextureDescriptor::storage_mode.

◆ TEST_P() [340/384]

impeller::testing::TEST_P ( GaussianBlurFilterContentsTest  ,
CoverageWithEffectTransform   
)

Definition at line 132 of file gaussian_blur_filter_contents_unittests.cc.

132  {
133  TextureDescriptor desc = {
134  .storage_mode = StorageMode::kDevicePrivate,
135  .format = PixelFormat::kB8G8R8A8UNormInt,
136  .size = ISize(100, 100),
137  };
138  Scalar sigma_radius_1 = CalculateSigmaForBlurRadius(1.0);
139  GaussianBlurFilterContents contents(/*sigma_x=*/sigma_radius_1,
140  /*sigma_y=*/sigma_radius_1,
141  Entity::TileMode::kDecal);
142  std::shared_ptr<Texture> texture =
143  GetContentContext()->GetContext()->GetResourceAllocator()->CreateTexture(
144  desc);
145  FilterInput::Vector inputs = {FilterInput::Make(texture)};
146  Entity entity;
147  entity.SetTransform(Matrix::MakeTranslation({100, 100, 0}));
148  std::optional<Rect> coverage = contents.GetFilterCoverage(
149  inputs, entity, /*effect_transform=*/Matrix::MakeScale({2.0, 2.0, 1.0}));
150  EXPECT_TRUE(coverage.has_value());
151  if (coverage.has_value()) {
152  EXPECT_RECT_NEAR(coverage.value(),
153  Rect::MakeLTRB(100 - 2, 100 - 2, 200 + 2, 200 + 2));
154  }
155 }

References EXPECT_RECT_NEAR, impeller::GaussianBlurFilterContents::GetFilterCoverage(), impeller::kB8G8R8A8UNormInt, impeller::Entity::kDecal, impeller::kDevicePrivate, impeller::FilterInput::Make(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::Entity::SetTransform(), and impeller::TextureDescriptor::storage_mode.

◆ TEST_P() [341/384]

impeller::testing::TEST_P ( GaussianBlurFilterContentsTest  ,
CoverageWithTexture   
)

Definition at line 108 of file gaussian_blur_filter_contents_unittests.cc.

108  {
109  TextureDescriptor desc = {
110  .storage_mode = StorageMode::kDevicePrivate,
111  .format = PixelFormat::kB8G8R8A8UNormInt,
112  .size = ISize(100, 100),
113  };
114  Scalar sigma_radius_1 = CalculateSigmaForBlurRadius(1.0);
115  GaussianBlurFilterContents contents(/*sigma_X=*/sigma_radius_1,
116  /*sigma_y=*/sigma_radius_1,
117  Entity::TileMode::kDecal);
118  std::shared_ptr<Texture> texture =
119  GetContentContext()->GetContext()->GetResourceAllocator()->CreateTexture(
120  desc);
121  FilterInput::Vector inputs = {FilterInput::Make(texture)};
122  Entity entity;
123  entity.SetTransform(Matrix::MakeTranslation({100, 100, 0}));
124  std::optional<Rect> coverage =
125  contents.GetFilterCoverage(inputs, entity, /*effect_transform=*/Matrix());
126  EXPECT_TRUE(coverage.has_value());
127  if (coverage.has_value()) {
128  EXPECT_RECT_NEAR(coverage.value(), Rect::MakeLTRB(99, 99, 201, 201));
129  }
130 }

References EXPECT_RECT_NEAR, impeller::GaussianBlurFilterContents::GetFilterCoverage(), impeller::kB8G8R8A8UNormInt, impeller::Entity::kDecal, impeller::kDevicePrivate, impeller::FilterInput::Make(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeTranslation(), impeller::Entity::SetTransform(), and impeller::TextureDescriptor::storage_mode.

◆ TEST_P() [342/384]

impeller::testing::TEST_P ( GaussianBlurFilterContentsTest  ,
RenderCoverageMatchesGetCoverage   
)

Definition at line 176 of file gaussian_blur_filter_contents_unittests.cc.

176  {
177  TextureDescriptor desc = {
178  .storage_mode = StorageMode::kDevicePrivate,
179  .format = PixelFormat::kB8G8R8A8UNormInt,
180  .size = ISize(100, 100),
181  };
182  std::shared_ptr<Texture> texture = MakeTexture(desc);
183  Scalar sigma_radius_1 = CalculateSigmaForBlurRadius(1.0);
184  auto contents = std::make_unique<GaussianBlurFilterContents>(
185  sigma_radius_1, sigma_radius_1, Entity::TileMode::kDecal);
186  contents->SetInputs({FilterInput::Make(texture)});
187  std::shared_ptr<ContentContext> renderer = GetContentContext();
188 
189  Entity entity;
190  std::optional<Entity> result =
191  contents->GetEntity(*renderer, entity, /*coverage_hint=*/{});
192  EXPECT_TRUE(result.has_value());
193  if (result.has_value()) {
194  EXPECT_EQ(result.value().GetBlendMode(), BlendMode::kSourceOver);
195  std::optional<Rect> result_coverage = result.value().GetCoverage();
196  std::optional<Rect> contents_coverage = contents->GetCoverage(entity);
197  EXPECT_TRUE(result_coverage.has_value());
198  EXPECT_TRUE(contents_coverage.has_value());
199  if (result_coverage.has_value() && contents_coverage.has_value()) {
200  EXPECT_TRUE(RectNear(contents_coverage.value(),
201  Rect::MakeLTRB(-1, -1, 101, 101)));
202  EXPECT_TRUE(
203  RectNear(result_coverage.value(), Rect::MakeLTRB(-1, -1, 101, 101)));
204  }
205  }
206 }

References impeller::kB8G8R8A8UNormInt, impeller::Entity::kDecal, impeller::kDevicePrivate, impeller::kSourceOver, impeller::FilterInput::Make(), impeller::TRect< Scalar >::MakeLTRB(), RectNear(), and impeller::TextureDescriptor::storage_mode.

◆ TEST_P() [343/384]

impeller::testing::TEST_P ( GaussianBlurFilterContentsTest  ,
RenderCoverageMatchesGetCoverageRotated   
)

Definition at line 243 of file gaussian_blur_filter_contents_unittests.cc.

244  {
245  TextureDescriptor desc = {
246  .storage_mode = StorageMode::kDevicePrivate,
247  .format = PixelFormat::kB8G8R8A8UNormInt,
248  .size = ISize(400, 300),
249  };
250  std::shared_ptr<Texture> texture = MakeTexture(desc);
251  Scalar sigma_radius_1 = CalculateSigmaForBlurRadius(1.0);
252  auto contents = std::make_unique<GaussianBlurFilterContents>(
253  sigma_radius_1, sigma_radius_1, Entity::TileMode::kDecal);
254  contents->SetInputs({FilterInput::Make(texture)});
255  std::shared_ptr<ContentContext> renderer = GetContentContext();
256 
257  Entity entity;
258  // Rotate around the top left corner, then push it over to (100, 100).
259  entity.SetTransform(Matrix::MakeTranslation({400, 100, 0}) *
260  Matrix::MakeRotationZ(Degrees(90.0)));
261  std::optional<Entity> result =
262  contents->GetEntity(*renderer, entity, /*coverage_hint=*/{});
263  EXPECT_TRUE(result.has_value());
264  if (result.has_value()) {
265  EXPECT_EQ(result.value().GetBlendMode(), BlendMode::kSourceOver);
266  std::optional<Rect> result_coverage = result.value().GetCoverage();
267  std::optional<Rect> contents_coverage = contents->GetCoverage(entity);
268  EXPECT_TRUE(result_coverage.has_value());
269  EXPECT_TRUE(contents_coverage.has_value());
270  if (result_coverage.has_value() && contents_coverage.has_value()) {
271  EXPECT_TRUE(RectNear(contents_coverage.value(),
272  Rect::MakeLTRB(99, 99, 401, 501)));
273  EXPECT_TRUE(
274  RectNear(result_coverage.value(), Rect::MakeLTRB(99, 99, 401, 501)));
275  }
276  }
277 }

References impeller::kB8G8R8A8UNormInt, impeller::Entity::kDecal, impeller::kDevicePrivate, impeller::kSourceOver, impeller::FilterInput::Make(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeRotationZ(), impeller::Matrix::MakeTranslation(), RectNear(), impeller::Entity::SetTransform(), and impeller::TextureDescriptor::storage_mode.

◆ TEST_P() [344/384]

impeller::testing::TEST_P ( GaussianBlurFilterContentsTest  ,
RenderCoverageMatchesGetCoverageTranslate   
)

Definition at line 208 of file gaussian_blur_filter_contents_unittests.cc.

209  {
210  TextureDescriptor desc = {
211  .storage_mode = StorageMode::kDevicePrivate,
212  .format = PixelFormat::kB8G8R8A8UNormInt,
213  .size = ISize(100, 100),
214  };
215  std::shared_ptr<Texture> texture = MakeTexture(desc);
216  Scalar sigma_radius_1 = CalculateSigmaForBlurRadius(1.0);
217  auto contents = std::make_unique<GaussianBlurFilterContents>(
218  sigma_radius_1, sigma_radius_1, Entity::TileMode::kDecal);
219  contents->SetInputs({FilterInput::Make(texture)});
220  std::shared_ptr<ContentContext> renderer = GetContentContext();
221 
222  Entity entity;
223  entity.SetTransform(Matrix::MakeTranslation({100, 200, 0}));
224  std::optional<Entity> result =
225  contents->GetEntity(*renderer, entity, /*coverage_hint=*/{});
226 
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(99, 199, 201, 301)));
237  EXPECT_TRUE(
238  RectNear(result_coverage.value(), Rect::MakeLTRB(99, 199, 201, 301)));
239  }
240  }
241 }

References impeller::kB8G8R8A8UNormInt, impeller::Entity::kDecal, impeller::kDevicePrivate, impeller::kSourceOver, impeller::FilterInput::Make(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeTranslation(), RectNear(), impeller::Entity::SetTransform(), and impeller::TextureDescriptor::storage_mode.

◆ TEST_P() [345/384]

impeller::testing::TEST_P ( GaussianBlurFilterContentsTest  ,
TextureContentsWithDestinationRect   
)

Definition at line 297 of file gaussian_blur_filter_contents_unittests.cc.

297  {
298  TextureDescriptor desc = {
299  .storage_mode = StorageMode::kDevicePrivate,
300  .format = PixelFormat::kB8G8R8A8UNormInt,
301  .size = ISize(100, 100),
302  };
303 
304  std::shared_ptr<Texture> texture = MakeTexture(desc);
305  auto texture_contents = std::make_shared<TextureContents>();
306  texture_contents->SetSourceRect(Rect::MakeSize(texture->GetSize()));
307  texture_contents->SetTexture(texture);
308  texture_contents->SetDestinationRect(Rect::MakeXYWH(
309  50, 40, texture->GetSize().width, texture->GetSize().height));
310 
311  Scalar sigma_radius_1 = CalculateSigmaForBlurRadius(1.0);
312  auto contents = std::make_unique<GaussianBlurFilterContents>(
313  sigma_radius_1, sigma_radius_1, Entity::TileMode::kDecal);
314  contents->SetInputs({FilterInput::Make(texture_contents)});
315  std::shared_ptr<ContentContext> renderer = GetContentContext();
316 
317  Entity entity;
318  std::optional<Entity> result =
319  contents->GetEntity(*renderer, entity, /*coverage_hint=*/{});
320  EXPECT_TRUE(result.has_value());
321  if (result.has_value()) {
322  EXPECT_EQ(result.value().GetBlendMode(), BlendMode::kSourceOver);
323  std::optional<Rect> result_coverage = result.value().GetCoverage();
324  std::optional<Rect> contents_coverage = contents->GetCoverage(entity);
325  EXPECT_TRUE(result_coverage.has_value());
326  EXPECT_TRUE(contents_coverage.has_value());
327  if (result_coverage.has_value() && contents_coverage.has_value()) {
328  EXPECT_TRUE(RectNear(result_coverage.value(), contents_coverage.value()));
329  EXPECT_TRUE(RectNear(result_coverage.value(),
330  Rect::MakeLTRB(49.f, 39.f, 151.f, 141.f)));
331  }
332  }
333 }

References impeller::kB8G8R8A8UNormInt, impeller::Entity::kDecal, impeller::kDevicePrivate, impeller::kSourceOver, impeller::FilterInput::Make(), impeller::TRect< Scalar >::MakeLTRB(), impeller::TRect< Scalar >::MakeSize(), impeller::TRect< Scalar >::MakeXYWH(), RectNear(), and impeller::TextureDescriptor::storage_mode.

◆ TEST_P() [346/384]

impeller::testing::TEST_P ( GaussianBlurFilterContentsTest  ,
TextureContentsWithDestinationRectScaled   
)

Definition at line 335 of file gaussian_blur_filter_contents_unittests.cc.

336  {
337  TextureDescriptor desc = {
338  .storage_mode = StorageMode::kDevicePrivate,
339  .format = PixelFormat::kB8G8R8A8UNormInt,
340  .size = ISize(100, 100),
341  };
342 
343  std::shared_ptr<Texture> texture = MakeTexture(desc);
344  auto texture_contents = std::make_shared<TextureContents>();
345  texture_contents->SetSourceRect(Rect::MakeSize(texture->GetSize()));
346  texture_contents->SetTexture(texture);
347  texture_contents->SetDestinationRect(Rect::MakeXYWH(
348  50, 40, texture->GetSize().width, texture->GetSize().height));
349 
350  Scalar sigma_radius_1 = CalculateSigmaForBlurRadius(1.0);
351  auto contents = std::make_unique<GaussianBlurFilterContents>(
352  sigma_radius_1, sigma_radius_1, Entity::TileMode::kDecal);
353  contents->SetInputs({FilterInput::Make(texture_contents)});
354  std::shared_ptr<ContentContext> renderer = GetContentContext();
355 
356  Entity entity;
357  entity.SetTransform(Matrix::MakeScale({2.0, 2.0, 1.0}));
358  std::optional<Entity> result =
359  contents->GetEntity(*renderer, entity, /*coverage_hint=*/{});
360  EXPECT_TRUE(result.has_value());
361  if (result.has_value()) {
362  EXPECT_EQ(result.value().GetBlendMode(), BlendMode::kSourceOver);
363  std::optional<Rect> result_coverage = result.value().GetCoverage();
364  std::optional<Rect> contents_coverage = contents->GetCoverage(entity);
365  EXPECT_TRUE(result_coverage.has_value());
366  EXPECT_TRUE(contents_coverage.has_value());
367  if (result_coverage.has_value() && contents_coverage.has_value()) {
368  EXPECT_TRUE(RectNear(result_coverage.value(), contents_coverage.value()));
369  EXPECT_TRUE(RectNear(contents_coverage.value(),
370  Rect::MakeLTRB(98.f, 78.f, 302.f, 282.f)));
371  }
372  }
373 }

References impeller::kB8G8R8A8UNormInt, impeller::Entity::kDecal, impeller::kDevicePrivate, impeller::kSourceOver, impeller::FilterInput::Make(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeScale(), impeller::TRect< Scalar >::MakeSize(), impeller::TRect< Scalar >::MakeXYWH(), RectNear(), impeller::Entity::SetTransform(), and impeller::TextureDescriptor::storage_mode.

◆ TEST_P() [347/384]

impeller::testing::TEST_P ( RendererDartTest  ,
CanInstantiateFlutterGPUContext   
)

Definition at line 107 of file renderer_dart_unittests.cc.

107  {
108  auto isolate = GetIsolate();
109  bool result = isolate->RunInIsolateScope([]() -> bool {
110  if (tonic::CheckAndHandleError(::Dart_Invoke(
111  Dart_RootLibrary(), tonic::ToDart("instantiateDefaultContext"), 0,
112  nullptr))) {
113  return false;
114  }
115  return true;
116  });
117 
118  ASSERT_TRUE(result);
119 }

◆ TEST_P() [348/384]

impeller::testing::TEST_P ( RendererDartTest  ,
CanRunDartInPlaygroundFrame   
)

Definition at line 87 of file renderer_dart_unittests.cc.

87  {
88  auto isolate = GetIsolate();
89 
90  SinglePassCallback callback = [&](RenderPass& pass) {
91  ImGui::Begin("Dart test", nullptr);
92  ImGui::Text(
93  "This test executes Dart code during the playground frame callback.");
94  ImGui::End();
95 
96  return isolate->RunInIsolateScope([]() -> bool {
97  if (tonic::CheckAndHandleError(::Dart_Invoke(
98  Dart_RootLibrary(), tonic::ToDart("sayHi"), 0, nullptr))) {
99  return false;
100  }
101  return true;
102  });
103  };
104  OpenPlaygroundHere(callback);
105 }

◆ TEST_P() [349/384]

impeller::testing::TEST_P ( RendererTest  ,
ArrayUniforms   
)

Definition at line 884 of file renderer_unittests.cc.

884  {
885  using VS = ArrayVertexShader;
886  using FS = ArrayFragmentShader;
887 
888  auto context = GetContext();
889  auto pipeline_descriptor =
890  PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
891  ASSERT_TRUE(pipeline_descriptor.has_value());
892  pipeline_descriptor->SetSampleCount(SampleCount::kCount4);
893  pipeline_descriptor->SetStencilAttachmentDescriptors(std::nullopt);
894  auto pipeline =
895  context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
896  ASSERT_TRUE(pipeline && pipeline->IsValid());
897 
898  SinglePassCallback callback = [&](RenderPass& pass) {
899  auto size = pass.GetRenderTargetSize();
900 
901  Command cmd;
902  cmd.pipeline = pipeline;
903  DEBUG_COMMAND_INFO(cmd, "Google Dots");
904  VertexBufferBuilder<VS::PerVertexData> builder;
905  builder.AddVertices({{Point()},
906  {Point(0, size.height)},
907  {Point(size.width, 0)},
908  {Point(size.width, 0)},
909  {Point(0, size.height)},
910  {Point(size.width, size.height)}});
911  cmd.BindVertices(builder.CreateVertexBuffer(pass.GetTransientsBuffer()));
912 
913  VS::FrameInfo frame_info;
914  EXPECT_EQ(pass.GetOrthographicTransform(), Matrix::MakeOrthographic(size));
915  frame_info.mvp =
916  pass.GetOrthographicTransform() * Matrix::MakeScale(GetContentScale());
917  VS::BindFrameInfo(cmd,
918  pass.GetTransientsBuffer().EmplaceUniform(frame_info));
919 
920  auto time = GetSecondsElapsed();
921  auto y_pos = [&time](float x) {
922  return 400 + 10 * std::cos(time * 5 + x / 6);
923  };
924 
925  FS::FragInfo fs_uniform = {
926  .circle_positions = {Point(430, y_pos(0)), Point(480, y_pos(1)),
927  Point(530, y_pos(2)), Point(580, y_pos(3))},
928  .colors = {Color::MakeRGBA8(66, 133, 244, 255),
929  Color::MakeRGBA8(219, 68, 55, 255),
930  Color::MakeRGBA8(244, 180, 0, 255),
931  Color::MakeRGBA8(15, 157, 88, 255)},
932  };
933  FS::BindFragInfo(cmd,
934  pass.GetTransientsBuffer().EmplaceUniform(fs_uniform));
935 
936  pass.AddCommand(std::move(cmd));
937  return true;
938  };
939  OpenPlaygroundHere(callback);
940 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::Command::BindVertices(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), DEBUG_COMMAND_INFO, impeller::kCount4, impeller::PipelineBuilder< VertexShader_, FragmentShader_ >::MakeDefaultPipelineDescriptor(), impeller::Matrix::MakeOrthographic(), impeller::Color::MakeRGBA8(), impeller::Matrix::MakeScale(), and impeller::Command::pipeline.

◆ TEST_P() [350/384]

impeller::testing::TEST_P ( RendererTest  ,
CanBlitTextureToBuffer   
)

Definition at line 569 of file renderer_unittests.cc.

569  {
570  auto context = GetContext();
571  ASSERT_TRUE(context);
572 
573  using VS = MipmapsVertexShader;
574  using FS = MipmapsFragmentShader;
575  auto desc = PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
576  ASSERT_TRUE(desc.has_value());
577  desc->SetSampleCount(SampleCount::kCount4);
578  desc->SetStencilAttachmentDescriptors(std::nullopt);
579  auto mipmaps_pipeline =
580  context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
581  ASSERT_TRUE(mipmaps_pipeline);
582 
583  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
584  auto boston = CreateTextureForFixture("boston.jpg");
585  ASSERT_TRUE(bridge && boston);
586  auto sampler = context->GetSamplerLibrary()->GetSampler({});
587  ASSERT_TRUE(sampler);
588 
589  TextureDescriptor texture_desc;
590  texture_desc.storage_mode = StorageMode::kHostVisible;
591  texture_desc.format = PixelFormat::kR8G8B8A8UNormInt;
592  texture_desc.size = bridge->GetTextureDescriptor().size;
593  texture_desc.mip_count = 1u;
594  texture_desc.usage =
595  static_cast<TextureUsageMask>(TextureUsage::kRenderTarget) |
596  static_cast<TextureUsageMask>(TextureUsage::kShaderWrite) |
597  static_cast<TextureUsageMask>(TextureUsage::kShaderRead);
598  DeviceBufferDescriptor device_buffer_desc;
599  device_buffer_desc.storage_mode = StorageMode::kHostVisible;
600  device_buffer_desc.size =
601  bridge->GetTextureDescriptor().GetByteSizeOfBaseMipLevel();
602  auto device_buffer =
603  context->GetResourceAllocator()->CreateBuffer(device_buffer_desc);
604 
605  // Vertex buffer.
606  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
607  vertex_builder.SetLabel("Box");
608  auto size = Point(boston->GetSize());
609  vertex_builder.AddVertices({
610  {{0, 0}, {0.0, 0.0}}, // 1
611  {{size.x, 0}, {1.0, 0.0}}, // 2
612  {{size.x, size.y}, {1.0, 1.0}}, // 3
613  {{0, 0}, {0.0, 0.0}}, // 1
614  {{size.x, size.y}, {1.0, 1.0}}, // 3
615  {{0, size.y}, {0.0, 1.0}}, // 4
616  });
617  auto vertex_buffer =
618  vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator());
619  ASSERT_TRUE(vertex_buffer);
620 
621  Renderer::RenderCallback callback = [&](RenderTarget& render_target) {
622  {
623  auto buffer = context->CreateCommandBuffer();
624  if (!buffer) {
625  return false;
626  }
627  buffer->SetLabel("Playground Command Buffer");
628  auto pass = buffer->CreateBlitPass();
629  if (!pass) {
630  return false;
631  }
632  pass->SetLabel("Playground Blit Pass");
633 
634  if (render_target.GetColorAttachments().empty()) {
635  return false;
636  }
637 
638  // Blit `bridge` to the top left corner of the texture.
639  pass->AddCopy(bridge, device_buffer);
640 
641  pass->EncodeCommands(context->GetResourceAllocator());
642 
643  if (!buffer->SubmitCommands()) {
644  return false;
645  }
646  }
647 
648  {
649  auto buffer = context->CreateCommandBuffer();
650  if (!buffer) {
651  return false;
652  }
653  buffer->SetLabel("Playground Command Buffer");
654 
655  auto pass = buffer->CreateRenderPass(render_target);
656  if (!pass) {
657  return false;
658  }
659  pass->SetLabel("Playground Render Pass");
660  {
661  Command cmd;
662  DEBUG_COMMAND_INFO(cmd, "Image");
663  cmd.pipeline = mipmaps_pipeline;
664 
665  cmd.BindVertices(vertex_buffer);
666 
667  VS::FrameInfo frame_info;
668  EXPECT_EQ(pass->GetOrthographicTransform(),
669  Matrix::MakeOrthographic(pass->GetRenderTargetSize()));
670  frame_info.mvp = pass->GetOrthographicTransform() *
671  Matrix::MakeScale(GetContentScale());
672  VS::BindFrameInfo(
673  cmd, pass->GetTransientsBuffer().EmplaceUniform(frame_info));
674 
675  FS::FragInfo frag_info;
676  frag_info.lod = 0;
677  FS::BindFragInfo(cmd,
678  pass->GetTransientsBuffer().EmplaceUniform(frag_info));
679 
680  auto sampler = context->GetSamplerLibrary()->GetSampler({});
681  auto buffer_view = device_buffer->AsBufferView();
682  auto texture =
683  context->GetResourceAllocator()->CreateTexture(texture_desc);
684  if (!texture->SetContents(buffer_view.contents,
685  buffer_view.range.length)) {
686  VALIDATION_LOG << "Could not upload texture to device memory";
687  return false;
688  }
689  FS::BindTex(cmd, texture, sampler);
690 
691  pass->AddCommand(std::move(cmd));
692  }
693  pass->EncodeCommands();
694  if (!buffer->SubmitCommands()) {
695  return false;
696  }
697  }
698  return true;
699  };
700  OpenPlaygroundHere(callback);
701 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::Command::BindVertices(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), DEBUG_COMMAND_INFO, impeller::TextureDescriptor::format, impeller::kCount4, impeller::kHostVisible, impeller::kR8G8B8A8UNormInt, impeller::kRenderTarget, impeller::kShaderRead, impeller::kShaderWrite, impeller::PipelineBuilder< VertexShader_, FragmentShader_ >::MakeDefaultPipelineDescriptor(), impeller::Matrix::MakeOrthographic(), impeller::Matrix::MakeScale(), impeller::TextureDescriptor::mip_count, impeller::Command::pipeline, impeller::VertexBufferBuilder< VertexType_, IndexType_ >::SetLabel(), impeller::DeviceBufferDescriptor::size, impeller::TextureDescriptor::size, impeller::DeviceBufferDescriptor::storage_mode, impeller::TextureDescriptor::storage_mode, impeller::TextureDescriptor::usage, and VALIDATION_LOG.

◆ TEST_P() [351/384]

impeller::testing::TEST_P ( RendererTest  ,
CanBlitTextureToTexture   
)

Definition at line 454 of file renderer_unittests.cc.

454  {
455  auto context = GetContext();
456  ASSERT_TRUE(context);
457 
458  using VS = MipmapsVertexShader;
459  using FS = MipmapsFragmentShader;
460  auto desc = PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
461  ASSERT_TRUE(desc.has_value());
462  desc->SetSampleCount(SampleCount::kCount4);
463  desc->SetStencilAttachmentDescriptors(std::nullopt);
464  auto mipmaps_pipeline =
465  context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
466  ASSERT_TRUE(mipmaps_pipeline);
467 
468  TextureDescriptor texture_desc;
469  texture_desc.storage_mode = StorageMode::kHostVisible;
470  texture_desc.format = PixelFormat::kR8G8B8A8UNormInt;
471  texture_desc.size = {800, 600};
472  texture_desc.mip_count = 1u;
473  texture_desc.usage =
474  static_cast<TextureUsageMask>(TextureUsage::kRenderTarget) |
475  static_cast<TextureUsageMask>(TextureUsage::kShaderRead);
476  auto texture = context->GetResourceAllocator()->CreateTexture(texture_desc);
477  ASSERT_TRUE(texture);
478 
479  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
480  auto boston = CreateTextureForFixture("boston.jpg");
481  ASSERT_TRUE(bridge && boston);
482  auto sampler = context->GetSamplerLibrary()->GetSampler({});
483  ASSERT_TRUE(sampler);
484 
485  // Vertex buffer.
486  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
487  vertex_builder.SetLabel("Box");
488  auto size = Point(boston->GetSize());
489  vertex_builder.AddVertices({
490  {{0, 0}, {0.0, 0.0}}, // 1
491  {{size.x, 0}, {1.0, 0.0}}, // 2
492  {{size.x, size.y}, {1.0, 1.0}}, // 3
493  {{0, 0}, {0.0, 0.0}}, // 1
494  {{size.x, size.y}, {1.0, 1.0}}, // 3
495  {{0, size.y}, {0.0, 1.0}}, // 4
496  });
497  auto vertex_buffer =
498  vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator());
499  ASSERT_TRUE(vertex_buffer);
500 
501  Renderer::RenderCallback callback = [&](RenderTarget& render_target) {
502  auto buffer = context->CreateCommandBuffer();
503  if (!buffer) {
504  return false;
505  }
506  buffer->SetLabel("Playground Command Buffer");
507 
508  {
509  auto pass = buffer->CreateBlitPass();
510  if (!pass) {
511  return false;
512  }
513  pass->SetLabel("Playground Blit Pass");
514 
515  if (render_target.GetColorAttachments().empty()) {
516  return false;
517  }
518 
519  // Blit `bridge` to the top left corner of the texture.
520  pass->AddCopy(bridge, texture);
521 
522  if (!pass->EncodeCommands(context->GetResourceAllocator())) {
523  return false;
524  }
525  }
526 
527  {
528  auto pass = buffer->CreateRenderPass(render_target);
529  if (!pass) {
530  return false;
531  }
532  pass->SetLabel("Playground Render Pass");
533  {
534  Command cmd;
535  DEBUG_COMMAND_INFO(cmd, "Image");
536  cmd.pipeline = mipmaps_pipeline;
537 
538  cmd.BindVertices(vertex_buffer);
539 
540  VS::FrameInfo frame_info;
541  EXPECT_EQ(pass->GetOrthographicTransform(),
542  Matrix::MakeOrthographic(pass->GetRenderTargetSize()));
543  frame_info.mvp = pass->GetOrthographicTransform() *
544  Matrix::MakeScale(GetContentScale());
545  VS::BindFrameInfo(
546  cmd, pass->GetTransientsBuffer().EmplaceUniform(frame_info));
547 
548  FS::FragInfo frag_info;
549  frag_info.lod = 0;
550  FS::BindFragInfo(cmd,
551  pass->GetTransientsBuffer().EmplaceUniform(frag_info));
552 
553  auto sampler = context->GetSamplerLibrary()->GetSampler({});
554  FS::BindTex(cmd, texture, sampler);
555 
556  pass->AddCommand(std::move(cmd));
557  }
558  pass->EncodeCommands();
559  }
560 
561  if (!buffer->SubmitCommands()) {
562  return false;
563  }
564  return true;
565  };
566  OpenPlaygroundHere(callback);
567 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::Command::BindVertices(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), DEBUG_COMMAND_INFO, impeller::TextureDescriptor::format, impeller::kCount4, impeller::kHostVisible, impeller::kR8G8B8A8UNormInt, impeller::kRenderTarget, impeller::kShaderRead, impeller::PipelineBuilder< VertexShader_, FragmentShader_ >::MakeDefaultPipelineDescriptor(), impeller::Matrix::MakeOrthographic(), impeller::Matrix::MakeScale(), impeller::TextureDescriptor::mip_count, impeller::Command::pipeline, impeller::VertexBufferBuilder< VertexType_, IndexType_ >::SetLabel(), impeller::TextureDescriptor::size, impeller::TextureDescriptor::storage_mode, and impeller::TextureDescriptor::usage.

◆ TEST_P() [352/384]

impeller::testing::TEST_P ( RendererTest  ,
CanCreateBoxPrimitive   
)

Definition at line 46 of file renderer_unittests.cc.

46  {
47  using VS = BoxFadeVertexShader;
48  using FS = BoxFadeFragmentShader;
49  auto context = GetContext();
50  ASSERT_TRUE(context);
51  using BoxPipelineBuilder = PipelineBuilder<VS, FS>;
52  auto desc = BoxPipelineBuilder::MakeDefaultPipelineDescriptor(*context);
53  ASSERT_TRUE(desc.has_value());
54  desc->SetSampleCount(SampleCount::kCount4);
55  desc->SetStencilAttachmentDescriptors(std::nullopt);
56 
57  // Vertex buffer.
58  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
59  vertex_builder.SetLabel("Box");
60  vertex_builder.AddVertices({
61  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
62  {{800, 100, 0.0}, {1.0, 0.0}}, // 2
63  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
64  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
65  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
66  {{100, 800, 0.0}, {0.0, 1.0}}, // 4
67  });
68  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
69  auto boston = CreateTextureForFixture("boston.jpg");
70  ASSERT_TRUE(bridge && boston);
71  auto sampler = context->GetSamplerLibrary()->GetSampler({});
72  ASSERT_TRUE(sampler);
73  SinglePassCallback callback = [&](RenderPass& pass) {
74  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
75  static bool wireframe;
76  ImGui::Checkbox("Wireframe", &wireframe);
77  ImGui::End();
78 
79  desc->SetPolygonMode(wireframe ? PolygonMode::kLine : PolygonMode::kFill);
80  auto pipeline = context->GetPipelineLibrary()->GetPipeline(desc).Get();
81 
82  assert(pipeline && pipeline->IsValid());
83 
84  Command cmd;
85  DEBUG_COMMAND_INFO(cmd, "Box");
86  cmd.pipeline = pipeline;
87 
88  cmd.BindVertices(
89  vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator()));
90 
91  VS::UniformBuffer uniforms;
92  EXPECT_EQ(pass.GetOrthographicTransform(),
93  Matrix::MakeOrthographic(pass.GetRenderTargetSize()));
94  uniforms.mvp =
95  pass.GetOrthographicTransform() * Matrix::MakeScale(GetContentScale());
96  VS::BindUniformBuffer(cmd,
97  pass.GetTransientsBuffer().EmplaceUniform(uniforms));
98 
99  FS::FrameInfo frame_info;
100  frame_info.current_time = GetSecondsElapsed();
101  frame_info.cursor_position = GetCursorPosition();
102  frame_info.window_size.x = GetWindowSize().width;
103  frame_info.window_size.y = GetWindowSize().height;
104 
105  FS::BindFrameInfo(cmd,
106  pass.GetTransientsBuffer().EmplaceUniform(frame_info));
107  FS::BindContents1(cmd, boston, sampler);
108  FS::BindContents2(cmd, bridge, sampler);
109  if (!pass.AddCommand(std::move(cmd))) {
110  return false;
111  }
112  return true;
113  };
114  OpenPlaygroundHere(callback);
115 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::Command::BindVertices(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), DEBUG_COMMAND_INFO, impeller::kCount4, impeller::kFill, impeller::kLine, impeller::Matrix::MakeOrthographic(), impeller::Matrix::MakeScale(), impeller::Command::pipeline, and impeller::VertexBufferBuilder< VertexType_, IndexType_ >::SetLabel().

◆ TEST_P() [353/384]

impeller::testing::TEST_P ( RendererTest  ,
CanCreateCPUBackedTexture   
)

Definition at line 989 of file renderer_unittests.cc.

989  {
990  if (GetParam() == PlaygroundBackend::kOpenGLES) {
991  GTEST_SKIP_("CPU backed textures are not supported on OpenGLES.");
992  }
993 
994  auto context = GetContext();
995  auto allocator = context->GetResourceAllocator();
996  size_t dimension = 2;
997 
998  do {
999  ISize size(dimension, dimension);
1000  TextureDescriptor texture_descriptor;
1001  texture_descriptor.storage_mode = StorageMode::kHostVisible;
1002  texture_descriptor.format = PixelFormat::kR8G8B8A8UNormInt;
1003  texture_descriptor.size = size;
1004  auto row_bytes =
1005  std::max(static_cast<uint16_t>(size.width * 4),
1006  allocator->MinimumBytesPerRow(texture_descriptor.format));
1007  auto buffer_size = size.height * row_bytes;
1008 
1009  DeviceBufferDescriptor buffer_descriptor;
1010  buffer_descriptor.storage_mode = StorageMode::kHostVisible;
1011  buffer_descriptor.size = buffer_size;
1012 
1013  auto buffer = allocator->CreateBuffer(buffer_descriptor);
1014 
1015  ASSERT_TRUE(buffer);
1016 
1017  auto texture = buffer->AsTexture(*allocator, texture_descriptor, row_bytes);
1018 
1019  ASSERT_TRUE(texture);
1020  ASSERT_TRUE(texture->IsValid());
1021 
1022  dimension *= 2;
1023  } while (dimension <= 8192);
1024 }

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() [354/384]

impeller::testing::TEST_P ( RendererTest  ,
CanGenerateMipmaps   
)

Definition at line 703 of file renderer_unittests.cc.

703  {
704  auto context = GetContext();
705  ASSERT_TRUE(context);
706 
707  using VS = MipmapsVertexShader;
708  using FS = MipmapsFragmentShader;
709  auto desc = PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
710  ASSERT_TRUE(desc.has_value());
711  desc->SetSampleCount(SampleCount::kCount4);
712  desc->SetStencilAttachmentDescriptors(std::nullopt);
713  auto mipmaps_pipeline =
714  context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
715  ASSERT_TRUE(mipmaps_pipeline);
716 
717  auto boston = CreateTextureForFixture("boston.jpg", true);
718  ASSERT_TRUE(boston);
719 
720  // Vertex buffer.
721  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
722  vertex_builder.SetLabel("Box");
723  auto size = Point(boston->GetSize());
724  vertex_builder.AddVertices({
725  {{0, 0}, {0.0, 0.0}}, // 1
726  {{size.x, 0}, {1.0, 0.0}}, // 2
727  {{size.x, size.y}, {1.0, 1.0}}, // 3
728  {{0, 0}, {0.0, 0.0}}, // 1
729  {{size.x, size.y}, {1.0, 1.0}}, // 3
730  {{0, size.y}, {0.0, 1.0}}, // 4
731  });
732  auto vertex_buffer =
733  vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator());
734  ASSERT_TRUE(vertex_buffer);
735 
736  bool first_frame = true;
737  Renderer::RenderCallback callback = [&](RenderTarget& render_target) {
738  const char* mip_filter_names[] = {"Nearest", "Linear"};
739  const MipFilter mip_filters[] = {MipFilter::kNearest, MipFilter::kLinear};
740  const char* min_filter_names[] = {"Nearest", "Linear"};
741  const MinMagFilter min_filters[] = {MinMagFilter::kNearest,
742  MinMagFilter::kLinear};
743 
744  // UI state.
745  static int selected_mip_filter = 1;
746  static int selected_min_filter = 0;
747  static float lod = 4.5;
748 
749  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
750  ImGui::Combo("Mip filter", &selected_mip_filter, mip_filter_names,
751  sizeof(mip_filter_names) / sizeof(char*));
752  ImGui::Combo("Min filter", &selected_min_filter, min_filter_names,
753  sizeof(min_filter_names) / sizeof(char*));
754  ImGui::SliderFloat("LOD", &lod, 0, boston->GetMipCount() - 1);
755  ImGui::End();
756 
757  auto buffer = context->CreateCommandBuffer();
758  if (!buffer) {
759  return false;
760  }
761  buffer->SetLabel("Playground Command Buffer");
762 
763  if (first_frame) {
764  auto pass = buffer->CreateBlitPass();
765  if (!pass) {
766  return false;
767  }
768  pass->SetLabel("Playground Blit Pass");
769 
770  pass->GenerateMipmap(boston, "Boston Mipmap");
771 
772  pass->EncodeCommands(context->GetResourceAllocator());
773  }
774 
775  first_frame = false;
776 
777  {
778  auto pass = buffer->CreateRenderPass(render_target);
779  if (!pass) {
780  return false;
781  }
782  pass->SetLabel("Playground Render Pass");
783  {
784  Command cmd;
785  DEBUG_COMMAND_INFO(cmd, "Image LOD");
786  cmd.pipeline = mipmaps_pipeline;
787 
788  cmd.BindVertices(vertex_buffer);
789 
790  VS::FrameInfo frame_info;
791  EXPECT_EQ(pass->GetOrthographicTransform(),
792  Matrix::MakeOrthographic(pass->GetRenderTargetSize()));
793  frame_info.mvp = pass->GetOrthographicTransform() *
794  Matrix::MakeScale(GetContentScale());
795  VS::BindFrameInfo(
796  cmd, pass->GetTransientsBuffer().EmplaceUniform(frame_info));
797 
798  FS::FragInfo frag_info;
799  frag_info.lod = lod;
800  FS::BindFragInfo(cmd,
801  pass->GetTransientsBuffer().EmplaceUniform(frag_info));
802 
803  SamplerDescriptor sampler_desc;
804  sampler_desc.mip_filter = mip_filters[selected_mip_filter];
805  sampler_desc.min_filter = min_filters[selected_min_filter];
806  auto sampler = context->GetSamplerLibrary()->GetSampler(sampler_desc);
807  FS::BindTex(cmd, boston, sampler);
808 
809  pass->AddCommand(std::move(cmd));
810  }
811  pass->EncodeCommands();
812  }
813 
814  if (!buffer->SubmitCommands()) {
815  return false;
816  }
817  return true;
818  };
819  OpenPlaygroundHere(callback);
820 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::Command::BindVertices(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), DEBUG_COMMAND_INFO, impeller::kCount4, impeller::kLinear, impeller::kNearest, impeller::PipelineBuilder< VertexShader_, FragmentShader_ >::MakeDefaultPipelineDescriptor(), impeller::Matrix::MakeOrthographic(), impeller::Matrix::MakeScale(), impeller::SamplerDescriptor::min_filter, impeller::SamplerDescriptor::mip_filter, impeller::Command::pipeline, and impeller::VertexBufferBuilder< VertexType_, IndexType_ >::SetLabel().

◆ TEST_P() [355/384]

impeller::testing::TEST_P ( RendererTest  ,
CanLookupRenderTargetProperties   
)

Definition at line 1283 of file renderer_unittests.cc.

1283  {
1284  auto context = GetContext();
1285  auto cmd_buffer = context->CreateCommandBuffer();
1286  auto render_target_cache = std::make_shared<RenderTargetAllocator>(
1287  GetContext()->GetResourceAllocator());
1288 
1289  auto render_target =
1290  RenderTarget::CreateOffscreen(*context, *render_target_cache, {100, 100});
1291  auto render_pass = cmd_buffer->CreateRenderPass(render_target);
1292 
1293  EXPECT_EQ(render_pass->GetSampleCount(), render_target.GetSampleCount());
1294  EXPECT_EQ(render_pass->GetRenderTargetPixelFormat(),
1295  render_target.GetRenderTargetPixelFormat());
1296  EXPECT_EQ(render_pass->HasStencilAttachment(),
1297  render_target.GetStencilAttachment().has_value());
1298  EXPECT_EQ(render_pass->GetRenderTargetSize(),
1299  render_target.GetRenderTargetSize());
1300 }

References impeller::RenderTarget::CreateOffscreen().

◆ TEST_P() [356/384]

impeller::testing::TEST_P ( RendererTest  ,
CanPreAllocateCommands   
)

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 =
1275  RenderTarget::CreateOffscreen(*context, *render_target_cache, {100, 100});
1276  auto render_pass = cmd_buffer->CreateRenderPass(render_target);
1277 
1278  render_pass->ReserveCommands(100u);
1279 
1280  EXPECT_EQ(render_pass->GetCommands().capacity(), 100u);
1281 }

References impeller::RenderTarget::CreateOffscreen().

◆ TEST_P() [357/384]

impeller::testing::TEST_P ( RendererTest  ,
CanRenderInstanced   
)

Definition at line 386 of file renderer_unittests.cc.

386  {
387  if (GetParam() == PlaygroundBackend::kOpenGLES) {
388  GTEST_SKIP_("Instancing is not supported on OpenGL.");
389  }
390  using VS = InstancedDrawVertexShader;
391  using FS = InstancedDrawFragmentShader;
392 
393  VertexBufferBuilder<VS::PerVertexData> builder;
394 
395  ASSERT_EQ(Tessellator::Result::kSuccess,
396  Tessellator{}.Tessellate(
397  PathBuilder{}
398  .AddRect(Rect::MakeXYWH(10, 10, 100, 100))
399  .TakePath(FillType::kPositive),
400  1.0f,
401  [&builder](const float* vertices, size_t vertices_count,
402  const uint16_t* indices, size_t indices_count) {
403  for (auto i = 0u; i < vertices_count * 2; i += 2) {
404  VS::PerVertexData data;
405  data.vtx = {vertices[i], vertices[i + 1]};
406  builder.AppendVertex(data);
407  }
408  for (auto i = 0u; i < indices_count; i++) {
409  builder.AppendIndex(indices[i]);
410  }
411  return true;
412  }));
413 
414  ASSERT_NE(GetContext(), nullptr);
415  auto pipeline =
416  GetContext()
417  ->GetPipelineLibrary()
418  ->GetPipeline(PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(
419  *GetContext())
420  ->SetSampleCount(SampleCount::kCount4)
421  .SetStencilAttachmentDescriptors(std::nullopt))
422 
423  .Get();
424  ASSERT_TRUE(pipeline && pipeline->IsValid());
425 
426  Command cmd;
427  cmd.pipeline = pipeline;
428  DEBUG_COMMAND_INFO(cmd, "InstancedDraw");
429 
430  static constexpr size_t kInstancesCount = 5u;
431  VS::InstanceInfo<kInstancesCount> instances;
432  for (size_t i = 0; i < kInstancesCount; i++) {
433  instances.colors[i] = Color::Random();
434  }
435 
436  ASSERT_TRUE(OpenPlaygroundHere([&](RenderPass& pass) -> bool {
437  VS::FrameInfo frame_info;
438  EXPECT_EQ(pass.GetOrthographicTransform(),
439  Matrix::MakeOrthographic(pass.GetRenderTargetSize()));
440  frame_info.mvp =
441  pass.GetOrthographicTransform() * Matrix::MakeScale(GetContentScale());
442  VS::BindFrameInfo(cmd,
443  pass.GetTransientsBuffer().EmplaceUniform(frame_info));
444  VS::BindInstanceInfo(
445  cmd, pass.GetTransientsBuffer().EmplaceStorageBuffer(instances));
446  cmd.BindVertices(builder.CreateVertexBuffer(pass.GetTransientsBuffer()));
447 
448  cmd.instance_count = kInstancesCount;
449  pass.AddCommand(std::move(cmd));
450  return true;
451  }));
452 }

References impeller::RenderPass::AddCommand(), impeller::PathBuilder::AddRect(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AppendIndex(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AppendVertex(), impeller::Command::BindVertices(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), DEBUG_COMMAND_INFO, impeller::HostBuffer::EmplaceStorageBuffer(), impeller::HostBuffer::EmplaceUniform(), impeller::RenderPass::GetOrthographicTransform(), impeller::RenderPass::GetRenderTargetSize(), impeller::RenderPass::GetTransientsBuffer(), impeller::Command::instance_count, impeller::kCount4, impeller::kOpenGLES, impeller::kPositive, impeller::Tessellator::kSuccess, impeller::Matrix::MakeOrthographic(), impeller::Matrix::MakeScale(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Command::pipeline, impeller::Color::Random(), and impeller::Tessellator::Tessellate().

◆ TEST_P() [358/384]

impeller::testing::TEST_P ( RendererTest  ,
CanRenderMultiplePrimitives   
)

Definition at line 208 of file renderer_unittests.cc.

208  {
209  using VS = BoxFadeVertexShader;
210  using FS = BoxFadeFragmentShader;
211  auto context = GetContext();
212  ASSERT_TRUE(context);
213  using BoxPipelineBuilder = PipelineBuilder<VS, FS>;
214  auto desc = BoxPipelineBuilder::MakeDefaultPipelineDescriptor(*context);
215  ASSERT_TRUE(desc.has_value());
216  desc->SetSampleCount(SampleCount::kCount4);
217  desc->SetStencilAttachmentDescriptors(std::nullopt);
218  auto box_pipeline =
219  context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
220  ASSERT_TRUE(box_pipeline);
221 
222  // Vertex buffer.
223  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
224  vertex_builder.SetLabel("Box");
225  vertex_builder.AddVertices({
226  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
227  {{800, 100, 0.0}, {1.0, 0.0}}, // 2
228  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
229  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
230  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
231  {{100, 800, 0.0}, {0.0, 1.0}}, // 4
232  });
233  auto vertex_buffer =
234  vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator());
235  ASSERT_TRUE(vertex_buffer);
236 
237  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
238  auto boston = CreateTextureForFixture("boston.jpg");
239  ASSERT_TRUE(bridge && boston);
240  auto sampler = context->GetSamplerLibrary()->GetSampler({});
241  ASSERT_TRUE(sampler);
242 
243  SinglePassCallback callback = [&](RenderPass& pass) {
244  Command cmd;
245  DEBUG_COMMAND_INFO(cmd, "Box");
246  cmd.pipeline = box_pipeline;
247 
248  cmd.BindVertices(vertex_buffer);
249 
250  FS::FrameInfo frame_info;
251  frame_info.current_time = GetSecondsElapsed();
252  frame_info.cursor_position = GetCursorPosition();
253  frame_info.window_size.x = GetWindowSize().width;
254  frame_info.window_size.y = GetWindowSize().height;
255 
256  FS::BindFrameInfo(cmd,
257  pass.GetTransientsBuffer().EmplaceUniform(frame_info));
258  FS::BindContents1(cmd, boston, sampler);
259  FS::BindContents2(cmd, bridge, sampler);
260 
261  for (size_t i = 0; i < 1; i++) {
262  for (size_t j = 0; j < 1; j++) {
263  VS::UniformBuffer uniforms;
264  EXPECT_EQ(pass.GetOrthographicTransform(),
265  Matrix::MakeOrthographic(pass.GetRenderTargetSize()));
266  uniforms.mvp = pass.GetOrthographicTransform() *
267  Matrix::MakeScale(GetContentScale()) *
268  Matrix::MakeTranslation({i * 50.0f, j * 50.0f, 0.0f});
269  VS::BindUniformBuffer(
270  cmd, pass.GetTransientsBuffer().EmplaceUniform(uniforms));
271  if (!pass.AddCommand(std::move(cmd))) {
272  return false;
273  }
274  }
275  }
276 
277  return true;
278  };
279  OpenPlaygroundHere(callback);
280 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::Command::BindVertices(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), DEBUG_COMMAND_INFO, impeller::kCount4, impeller::Matrix::MakeOrthographic(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::Command::pipeline, and impeller::VertexBufferBuilder< VertexType_, IndexType_ >::SetLabel().

◆ TEST_P() [359/384]

impeller::testing::TEST_P ( RendererTest  ,
CanRenderPerspectiveCube   
)

Definition at line 117 of file renderer_unittests.cc.

117  {
118  using VS = ColorsVertexShader;
119  using FS = ColorsFragmentShader;
120  auto context = GetContext();
121  ASSERT_TRUE(context);
122  auto desc = PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
123  ASSERT_TRUE(desc.has_value());
124  desc->SetCullMode(CullMode::kBackFace);
125  desc->SetWindingOrder(WindingOrder::kCounterClockwise);
126  desc->SetSampleCount(SampleCount::kCount4);
127  desc->SetStencilAttachmentDescriptors(std::nullopt);
128  auto pipeline =
129  context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
130  ASSERT_TRUE(pipeline);
131 
132  struct Cube {
133  VS::PerVertexData vertices[8] = {
134  // -Z
135  {{-1, -1, -1}, Color::Red()},
136  {{1, -1, -1}, Color::Yellow()},
137  {{1, 1, -1}, Color::Green()},
138  {{-1, 1, -1}, Color::Blue()},
139  // +Z
140  {{-1, -1, 1}, Color::Green()},
141  {{1, -1, 1}, Color::Blue()},
142  {{1, 1, 1}, Color::Red()},
143  {{-1, 1, 1}, Color::Yellow()},
144  };
145  uint16_t indices[36] = {
146  1, 5, 2, 2, 5, 6, // +X
147  4, 0, 7, 7, 0, 3, // -X
148  4, 5, 0, 0, 5, 1, // +Y
149  3, 2, 7, 7, 2, 6, // -Y
150  5, 4, 6, 6, 4, 7, // +Z
151  0, 1, 3, 3, 1, 2, // -Z
152  };
153  } cube;
154 
155  VertexBuffer vertex_buffer;
156  {
157  auto device_buffer = context->GetResourceAllocator()->CreateBufferWithCopy(
158  reinterpret_cast<uint8_t*>(&cube), sizeof(cube));
159  vertex_buffer.vertex_buffer = {
160  .buffer = device_buffer,
161  .range = Range(offsetof(Cube, vertices), sizeof(Cube::vertices))};
162  vertex_buffer.index_buffer = {
163  .buffer = device_buffer,
164  .range = Range(offsetof(Cube, indices), sizeof(Cube::indices))};
165  vertex_buffer.vertex_count = 36;
166  vertex_buffer.index_type = IndexType::k16bit;
167  }
168 
169  auto sampler = context->GetSamplerLibrary()->GetSampler({});
170  ASSERT_TRUE(sampler);
171 
172  Vector3 euler_angles;
173  SinglePassCallback callback = [&](RenderPass& pass) {
174  static Degrees fov_y(60);
175  static Scalar distance = 10;
176 
177  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
178  ImGui::SliderFloat("Field of view", &fov_y.degrees, 0, 180);
179  ImGui::SliderFloat("Camera distance", &distance, 0, 30);
180  ImGui::End();
181 
182  Command cmd;
183  DEBUG_COMMAND_INFO(cmd, "Perspective Cube");
184  cmd.pipeline = pipeline;
185 
186  cmd.BindVertices(vertex_buffer);
187 
188  VS::UniformBuffer uniforms;
189  Scalar time = GetSecondsElapsed();
190  euler_angles = Vector3(0.19 * time, 0.7 * time, 0.43 * time);
191 
192  uniforms.mvp =
193  Matrix::MakePerspective(fov_y, pass.GetRenderTargetSize(), 0, 10) *
194  Matrix::MakeTranslation({0, 0, distance}) *
195  Matrix::MakeRotationX(Radians(euler_angles.x)) *
196  Matrix::MakeRotationY(Radians(euler_angles.y)) *
197  Matrix::MakeRotationZ(Radians(euler_angles.z));
198  VS::BindUniformBuffer(cmd,
199  pass.GetTransientsBuffer().EmplaceUniform(uniforms));
200  if (!pass.AddCommand(std::move(cmd))) {
201  return false;
202  }
203  return true;
204  };
205  OpenPlaygroundHere(callback);
206 }

References impeller::Command::BindVertices(), impeller::Color::Blue(), impeller::BufferView::buffer, DEBUG_COMMAND_INFO, impeller::Degrees::degrees, impeller::Color::Green(), impeller::VertexBuffer::index_buffer, impeller::VertexBuffer::index_type, impeller::k16bit, impeller::kBackFace, impeller::kCount4, impeller::kCounterClockwise, impeller::PipelineBuilder< VertexShader_, FragmentShader_ >::MakeDefaultPipelineDescriptor(), impeller::Matrix::MakePerspective(), impeller::Matrix::MakeRotationX(), impeller::Matrix::MakeRotationY(), impeller::Matrix::MakeRotationZ(), impeller::Matrix::MakeTranslation(), impeller::Command::pipeline, impeller::Color::Red(), impeller::VertexBuffer::vertex_buffer, impeller::VertexBuffer::vertex_count, impeller::Vector3::x, impeller::Vector3::y, impeller::Color::Yellow(), and impeller::Vector3::z.

◆ TEST_P() [360/384]

impeller::testing::TEST_P ( RendererTest  ,
CanRenderToTexture   
)

Definition at line 282 of file renderer_unittests.cc.

282  {
283  using VS = BoxFadeVertexShader;
284  using FS = BoxFadeFragmentShader;
285  auto context = GetContext();
286  ASSERT_TRUE(context);
287  using BoxPipelineBuilder = PipelineBuilder<VS, FS>;
288  auto pipeline_desc =
289  BoxPipelineBuilder::MakeDefaultPipelineDescriptor(*context);
290  pipeline_desc->SetSampleCount(SampleCount::kCount1);
291 
292  ASSERT_TRUE(pipeline_desc.has_value());
293  auto box_pipeline =
294  context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
295  ASSERT_TRUE(box_pipeline);
296 
297  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
298  vertex_builder.SetLabel("Box");
299  vertex_builder.AddVertices({
300  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
301  {{800, 100, 0.0}, {1.0, 0.0}}, // 2
302  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
303  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
304  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
305  {{100, 800, 0.0}, {0.0, 1.0}}, // 4
306  });
307  auto vertex_buffer =
308  vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator());
309  ASSERT_TRUE(vertex_buffer);
310 
311  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
312  auto boston = CreateTextureForFixture("boston.jpg");
313  ASSERT_TRUE(bridge && boston);
314  auto sampler = context->GetSamplerLibrary()->GetSampler({});
315  ASSERT_TRUE(sampler);
316  std::shared_ptr<RenderPass> r2t_pass;
317  auto cmd_buffer = context->CreateCommandBuffer();
318  ASSERT_TRUE(cmd_buffer);
319  {
320  ColorAttachment color0;
321  color0.load_action = LoadAction::kClear;
322  color0.store_action = StoreAction::kStore;
323 
324  TextureDescriptor texture_descriptor;
325  ASSERT_NE(pipeline_desc->GetColorAttachmentDescriptor(0u), nullptr);
326  texture_descriptor.format =
327  pipeline_desc->GetColorAttachmentDescriptor(0u)->format;
328  texture_descriptor.storage_mode = StorageMode::kHostVisible;
329  texture_descriptor.size = {400, 400};
330  texture_descriptor.mip_count = 1u;
331  texture_descriptor.usage =
332  static_cast<TextureUsageMask>(TextureUsage::kRenderTarget);
333 
334  color0.texture =
335  context->GetResourceAllocator()->CreateTexture(texture_descriptor);
336 
337  ASSERT_TRUE(color0.IsValid());
338 
339  color0.texture->SetLabel("r2t_target");
340 
341  StencilAttachment stencil0;
342  stencil0.load_action = LoadAction::kClear;
343  stencil0.store_action = StoreAction::kDontCare;
344  TextureDescriptor stencil_texture_desc;
345  stencil_texture_desc.storage_mode = StorageMode::kDeviceTransient;
346  stencil_texture_desc.size = texture_descriptor.size;
347  stencil_texture_desc.format = PixelFormat::kS8UInt;
348  stencil_texture_desc.usage =
349  static_cast<TextureUsageMask>(TextureUsage::kRenderTarget);
350  stencil0.texture =
351  context->GetResourceAllocator()->CreateTexture(stencil_texture_desc);
352 
353  RenderTarget r2t_desc;
354  r2t_desc.SetColorAttachment(color0, 0u);
355  r2t_desc.SetStencilAttachment(stencil0);
356  r2t_pass = cmd_buffer->CreateRenderPass(r2t_desc);
357  ASSERT_TRUE(r2t_pass && r2t_pass->IsValid());
358  }
359 
360  Command cmd;
361  DEBUG_COMMAND_INFO(cmd, "Box");
362  cmd.pipeline = box_pipeline;
363 
364  cmd.BindVertices(vertex_buffer);
365 
366  FS::FrameInfo frame_info;
367  frame_info.current_time = GetSecondsElapsed();
368  frame_info.cursor_position = GetCursorPosition();
369  frame_info.window_size.x = GetWindowSize().width;
370  frame_info.window_size.y = GetWindowSize().height;
371 
372  FS::BindFrameInfo(cmd,
373  r2t_pass->GetTransientsBuffer().EmplaceUniform(frame_info));
374  FS::BindContents1(cmd, boston, sampler);
375  FS::BindContents2(cmd, bridge, sampler);
376 
377  VS::UniformBuffer uniforms;
378  uniforms.mvp = Matrix::MakeOrthographic(ISize{1024, 768}) *
379  Matrix::MakeTranslation({50.0f, 50.0f, 0.0f});
380  VS::BindUniformBuffer(
381  cmd, r2t_pass->GetTransientsBuffer().EmplaceUniform(uniforms));
382  ASSERT_TRUE(r2t_pass->AddCommand(std::move(cmd)));
383  ASSERT_TRUE(r2t_pass->EncodeCommands());
384 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::Command::BindVertices(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), DEBUG_COMMAND_INFO, impeller::TextureDescriptor::format, impeller::Attachment::IsValid(), impeller::kClear, impeller::kCount1, impeller::kDeviceTransient, impeller::kDontCare, impeller::kHostVisible, impeller::kRenderTarget, impeller::kS8UInt, impeller::kStore, impeller::Attachment::load_action, impeller::Matrix::MakeOrthographic(), impeller::Matrix::MakeTranslation(), impeller::TextureDescriptor::mip_count, impeller::Command::pipeline, impeller::RenderTarget::SetColorAttachment(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::SetLabel(), impeller::RenderTarget::SetStencilAttachment(), impeller::TextureDescriptor::size, impeller::TextureDescriptor::storage_mode, impeller::Attachment::store_action, impeller::Attachment::texture, and impeller::TextureDescriptor::usage.

◆ TEST_P() [361/384]

impeller::testing::TEST_P ( RendererTest  ,
DefaultIndexBehavior   
)

Definition at line 1036 of file renderer_unittests.cc.

1036  {
1037  using VS = BoxFadeVertexShader;
1038 
1039  // Do not create any index buffer if no indices were provided.
1040  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
1041  ASSERT_EQ(vertex_builder.GetIndexType(), IndexType::kNone);
1042 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::GetIndexType(), and impeller::kNone.

◆ TEST_P() [362/384]

impeller::testing::TEST_P ( RendererTest  ,
DefaultIndexSize   
)

Definition at line 1026 of file renderer_unittests.cc.

1026  {
1027  using VS = BoxFadeVertexShader;
1028 
1029  // Default to 16bit index buffer size, as this is a reasonable default and
1030  // supported on all backends without extensions.
1031  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
1032  vertex_builder.AppendIndex(0u);
1033  ASSERT_EQ(vertex_builder.GetIndexType(), IndexType::k16bit);
1034 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AppendIndex(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::GetIndexType(), and impeller::k16bit.

◆ TEST_P() [363/384]

impeller::testing::TEST_P ( RendererTest  ,
InactiveUniforms   
)

Definition at line 942 of file renderer_unittests.cc.

942  {
943  using VS = InactiveUniformsVertexShader;
944  using FS = InactiveUniformsFragmentShader;
945 
946  auto context = GetContext();
947  auto pipeline_descriptor =
948  PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
949  ASSERT_TRUE(pipeline_descriptor.has_value());
950  pipeline_descriptor->SetSampleCount(SampleCount::kCount4);
951  pipeline_descriptor->SetStencilAttachmentDescriptors(std::nullopt);
952  auto pipeline =
953  context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
954  ASSERT_TRUE(pipeline && pipeline->IsValid());
955 
956  SinglePassCallback callback = [&](RenderPass& pass) {
957  auto size = pass.GetRenderTargetSize();
958 
959  Command cmd;
960  cmd.pipeline = pipeline;
961  DEBUG_COMMAND_INFO(cmd, "Inactive Uniform");
962  VertexBufferBuilder<VS::PerVertexData> builder;
963  builder.AddVertices({{Point()},
964  {Point(0, size.height)},
965  {Point(size.width, 0)},
966  {Point(size.width, 0)},
967  {Point(0, size.height)},
968  {Point(size.width, size.height)}});
969  cmd.BindVertices(builder.CreateVertexBuffer(pass.GetTransientsBuffer()));
970 
971  VS::FrameInfo frame_info;
972  EXPECT_EQ(pass.GetOrthographicTransform(), Matrix::MakeOrthographic(size));
973  frame_info.mvp =
974  pass.GetOrthographicTransform() * Matrix::MakeScale(GetContentScale());
975  VS::BindFrameInfo(cmd,
976  pass.GetTransientsBuffer().EmplaceUniform(frame_info));
977 
978  FS::FragInfo fs_uniform = {.unused_color = Color::Red(),
979  .color = Color::Green()};
980  FS::BindFragInfo(cmd,
981  pass.GetTransientsBuffer().EmplaceUniform(fs_uniform));
982 
983  pass.AddCommand(std::move(cmd));
984  return true;
985  };
986  OpenPlaygroundHere(callback);
987 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::Command::BindVertices(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), DEBUG_COMMAND_INFO, impeller::Color::Green(), impeller::kCount4, impeller::PipelineBuilder< VertexShader_, FragmentShader_ >::MakeDefaultPipelineDescriptor(), impeller::Matrix::MakeOrthographic(), impeller::Matrix::MakeScale(), impeller::Command::pipeline, and impeller::Color::Red().

◆ TEST_P() [364/384]

impeller::testing::TEST_P ( RendererTest  ,
StencilMask   
)

Definition at line 1114 of file renderer_unittests.cc.

1114  {
1115  using VS = BoxFadeVertexShader;
1116  using FS = BoxFadeFragmentShader;
1117  auto context = GetContext();
1118  ASSERT_TRUE(context);
1119  using BoxFadePipelineBuilder = PipelineBuilder<VS, FS>;
1120  auto desc = BoxFadePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
1121  ASSERT_TRUE(desc.has_value());
1122 
1123  // Vertex buffer.
1124  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
1125  vertex_builder.SetLabel("Box");
1126  vertex_builder.AddVertices({
1127  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
1128  {{800, 100, 0.0}, {1.0, 0.0}}, // 2
1129  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
1130  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
1131  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
1132  {{100, 800, 0.0}, {0.0, 1.0}}, // 4
1133  });
1134  auto vertex_buffer =
1135  vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator());
1136  ASSERT_TRUE(vertex_buffer);
1137 
1138  desc->SetSampleCount(SampleCount::kCount4);
1139  desc->SetStencilAttachmentDescriptors(std::nullopt);
1140 
1141  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
1142  auto boston = CreateTextureForFixture("boston.jpg");
1143  ASSERT_TRUE(bridge && boston);
1144  auto sampler = context->GetSamplerLibrary()->GetSampler({});
1145  ASSERT_TRUE(sampler);
1146 
1147  static bool mirror = false;
1148  static int stencil_reference_write = 0xFF;
1149  static int stencil_reference_read = 0x1;
1150  std::vector<uint8_t> stencil_contents;
1151  static int last_stencil_contents_reference_value = 0;
1152  static int current_front_compare =
1153  CompareFunctionUI().IndexOf(CompareFunction::kLessEqual);
1154  static int current_back_compare =
1155  CompareFunctionUI().IndexOf(CompareFunction::kLessEqual);
1156  Renderer::RenderCallback callback = [&](RenderTarget& render_target) {
1157  auto buffer = context->CreateCommandBuffer();
1158  if (!buffer) {
1159  return false;
1160  }
1161  buffer->SetLabel("Playground Command Buffer");
1162 
1163  {
1164  // Configure the stencil attachment for the test.
1165  RenderTarget::AttachmentConfig stencil_config;
1166  stencil_config.load_action = LoadAction::kLoad;
1167  stencil_config.store_action = StoreAction::kDontCare;
1168  stencil_config.storage_mode = StorageMode::kHostVisible;
1169  auto render_target_allocator =
1170  RenderTargetAllocator(context->GetResourceAllocator());
1171  render_target.SetupStencilAttachment(*context, render_target_allocator,
1172  render_target.GetRenderTargetSize(),
1173  true, "stencil", stencil_config);
1174  // Fill the stencil buffer with an checkerboard pattern.
1175  const auto target_width = render_target.GetRenderTargetSize().width;
1176  const auto target_height = render_target.GetRenderTargetSize().height;
1177  const size_t target_size = target_width * target_height;
1178  if (stencil_contents.size() != target_size ||
1179  last_stencil_contents_reference_value != stencil_reference_write) {
1180  stencil_contents.resize(target_size);
1181  last_stencil_contents_reference_value = stencil_reference_write;
1182  for (int y = 0; y < target_height; y++) {
1183  for (int x = 0; x < target_width; x++) {
1184  const auto index = y * target_width + x;
1185  const auto kCheckSize = 64;
1186  const auto value =
1187  (((y / kCheckSize) + (x / kCheckSize)) % 2 == 0) *
1188  stencil_reference_write;
1189  stencil_contents[index] = value;
1190  }
1191  }
1192  }
1193  if (!render_target.GetStencilAttachment()->texture->SetContents(
1194  stencil_contents.data(), stencil_contents.size(), 0, false)) {
1195  VALIDATION_LOG << "Could not upload stencil contents to device memory";
1196  return false;
1197  }
1198  auto pass = buffer->CreateRenderPass(render_target);
1199  if (!pass) {
1200  return false;
1201  }
1202  pass->SetLabel("Stencil Buffer");
1203  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1204  ImGui::SliderInt("Stencil Write Value", &stencil_reference_write, 0,
1205  0xFF);
1206  ImGui::SliderInt("Stencil Compare Value", &stencil_reference_read, 0,
1207  0xFF);
1208  ImGui::Checkbox("Back face mode", &mirror);
1209  ImGui::ListBox("Front face compare function", &current_front_compare,
1210  CompareFunctionUI().labels(), CompareFunctionUI().size());
1211  ImGui::ListBox("Back face compare function", &current_back_compare,
1212  CompareFunctionUI().labels(), CompareFunctionUI().size());
1213  ImGui::End();
1214 
1215  StencilAttachmentDescriptor front;
1216  front.stencil_compare =
1217  CompareFunctionUI().FunctionOf(current_front_compare);
1218  StencilAttachmentDescriptor back;
1219  back.stencil_compare =
1220  CompareFunctionUI().FunctionOf(current_back_compare);
1221  desc->SetStencilAttachmentDescriptors(front, back);
1222  auto pipeline = context->GetPipelineLibrary()->GetPipeline(desc).Get();
1223 
1224  assert(pipeline && pipeline->IsValid());
1225 
1226  Command cmd;
1227  DEBUG_COMMAND_INFO(cmd, "Box");
1228  cmd.pipeline = pipeline;
1229  cmd.stencil_reference = stencil_reference_read;
1230 
1231  cmd.BindVertices(vertex_buffer);
1232 
1233  VS::UniformBuffer uniforms;
1234  EXPECT_EQ(pass->GetOrthographicTransform(),
1235  Matrix::MakeOrthographic(pass->GetRenderTargetSize()));
1236  uniforms.mvp = pass->GetOrthographicTransform() *
1237  Matrix::MakeScale(GetContentScale());
1238  if (mirror) {
1239  uniforms.mvp = Matrix::MakeScale(Vector2(-1, 1)) * uniforms.mvp;
1240  }
1241  VS::BindUniformBuffer(
1242  cmd, pass->GetTransientsBuffer().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(cmd,
1251  pass->GetTransientsBuffer().EmplaceUniform(frame_info));
1252  FS::BindContents1(cmd, boston, sampler);
1253  FS::BindContents2(cmd, bridge, sampler);
1254  if (!pass->AddCommand(std::move(cmd))) {
1255  return false;
1256  }
1257  pass->EncodeCommands();
1258  }
1259 
1260  if (!buffer->SubmitCommands()) {
1261  return false;
1262  }
1263  return true;
1264  };
1265  OpenPlaygroundHere(callback);
1266 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::Command::BindVertices(), CompareFunctionUI(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), DEBUG_COMMAND_INFO, impeller::testing::CompareFunctionUIData::FunctionOf(), impeller::testing::CompareFunctionUIData::IndexOf(), impeller::kCount4, impeller::kDontCare, impeller::kHostVisible, impeller::kLessEqual, impeller::kLoad, impeller::RenderTarget::AttachmentConfig::load_action, impeller::Matrix::MakeOrthographic(), impeller::Matrix::MakeScale(), impeller::Command::pipeline, impeller::VertexBufferBuilder< VertexType_, IndexType_ >::SetLabel(), impeller::StencilAttachmentDescriptor::stencil_compare, impeller::Command::stencil_reference, impeller::RenderTarget::AttachmentConfig::storage_mode, impeller::RenderTarget::AttachmentConfig::store_action, and VALIDATION_LOG.

◆ TEST_P() [365/384]

impeller::testing::TEST_P ( RendererTest  ,
TheImpeller   
)

Definition at line 822 of file renderer_unittests.cc.

822  {
823  using VS = ImpellerVertexShader;
824  using FS = ImpellerFragmentShader;
825 
826  auto context = GetContext();
827  auto pipeline_descriptor =
828  PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
829  ASSERT_TRUE(pipeline_descriptor.has_value());
830  pipeline_descriptor->SetSampleCount(SampleCount::kCount4);
831  pipeline_descriptor->SetStencilAttachmentDescriptors(std::nullopt);
832  auto pipeline =
833  context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
834  ASSERT_TRUE(pipeline && pipeline->IsValid());
835 
836  auto blue_noise = CreateTextureForFixture("blue_noise.png");
837  SamplerDescriptor noise_sampler_desc;
838  noise_sampler_desc.width_address_mode = SamplerAddressMode::kRepeat;
839  noise_sampler_desc.height_address_mode = SamplerAddressMode::kRepeat;
840  auto noise_sampler =
841  context->GetSamplerLibrary()->GetSampler(noise_sampler_desc);
842 
843  auto cube_map = CreateTextureCubeForFixture(
844  {"table_mountain_px.png", "table_mountain_nx.png",
845  "table_mountain_py.png", "table_mountain_ny.png",
846  "table_mountain_pz.png", "table_mountain_nz.png"});
847  auto cube_map_sampler = context->GetSamplerLibrary()->GetSampler({});
848 
849  SinglePassCallback callback = [&](RenderPass& pass) {
850  auto size = pass.GetRenderTargetSize();
851 
852  Command cmd;
853  cmd.pipeline = pipeline;
854  DEBUG_COMMAND_INFO(cmd, "Impeller SDF scene");
855  VertexBufferBuilder<VS::PerVertexData> builder;
856  builder.AddVertices({{Point()},
857  {Point(0, size.height)},
858  {Point(size.width, 0)},
859  {Point(size.width, 0)},
860  {Point(0, size.height)},
861  {Point(size.width, size.height)}});
862  cmd.BindVertices(builder.CreateVertexBuffer(pass.GetTransientsBuffer()));
863 
864  VS::FrameInfo frame_info;
865  EXPECT_EQ(pass.GetOrthographicTransform(), Matrix::MakeOrthographic(size));
866  frame_info.mvp = pass.GetOrthographicTransform();
867  VS::BindFrameInfo(cmd,
868  pass.GetTransientsBuffer().EmplaceUniform(frame_info));
869 
870  FS::FragInfo fs_uniform;
871  fs_uniform.texture_size = Point(size);
872  fs_uniform.time = GetSecondsElapsed();
873  FS::BindFragInfo(cmd,
874  pass.GetTransientsBuffer().EmplaceUniform(fs_uniform));
875  FS::BindBlueNoise(cmd, blue_noise, noise_sampler);
876  FS::BindCubeMap(cmd, cube_map, cube_map_sampler);
877 
878  pass.AddCommand(std::move(cmd));
879  return true;
880  };
881  OpenPlaygroundHere(callback);
882 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::Command::BindVertices(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), DEBUG_COMMAND_INFO, impeller::SamplerDescriptor::height_address_mode, impeller::kCount4, impeller::kRepeat, impeller::PipelineBuilder< VertexShader_, FragmentShader_ >::MakeDefaultPipelineDescriptor(), impeller::Matrix::MakeOrthographic(), impeller::Command::pipeline, and impeller::SamplerDescriptor::width_address_mode.

◆ TEST_P() [366/384]

impeller::testing::TEST_P ( RendererTest  ,
VertexBufferBuilder   
)

Definition at line 1044 of file renderer_unittests.cc.

1044  {
1045  // Does not create index buffer if one is provided.
1046  using VS = BoxFadeVertexShader;
1047  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
1048  vertex_builder.SetLabel("Box");
1049  vertex_builder.AddVertices({
1050  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
1051  {{800, 100, 0.0}, {1.0, 0.0}}, // 2
1052  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
1053  {{100, 800, 0.0}, {0.0, 1.0}}, // 4
1054  });
1055  vertex_builder.AppendIndex(0);
1056  vertex_builder.AppendIndex(1);
1057  vertex_builder.AppendIndex(2);
1058  vertex_builder.AppendIndex(1);
1059  vertex_builder.AppendIndex(2);
1060  vertex_builder.AppendIndex(3);
1061 
1062  ASSERT_EQ(vertex_builder.GetIndexCount(), 6u);
1063  ASSERT_EQ(vertex_builder.GetVertexCount(), 4u);
1064 }

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() [367/384]

impeller::testing::TEST_P ( RuntimeStageTest  ,
CanCreatePipelineFromRuntimeStage   
)

Definition at line 245 of file runtime_stage_unittests.cc.

245  {
246  if (!BackendSupportsFragmentProgram()) {
247  GTEST_SKIP_("This backend doesn't support runtime effects.");
248  }
249  auto stages = OpenAssetAsRuntimeStage("ink_sparkle.frag.iplr");
250  auto stage = stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
251 
252  ASSERT_TRUE(stage);
253  ASSERT_NE(stage, nullptr);
254  ASSERT_TRUE(RegisterStage(*stage));
255  auto library = GetContext()->GetShaderLibrary();
256  using VS = SimpleVertexShader;
257  PipelineDescriptor desc;
258  desc.SetLabel("Runtime Stage InkSparkle");
259  desc.AddStageEntrypoint(
260  library->GetFunction(VS::kEntrypointName, ShaderStage::kVertex));
261  desc.AddStageEntrypoint(
262  library->GetFunction(stage->GetEntrypoint(), ShaderStage::kFragment));
263  auto vertex_descriptor = std::make_shared<VertexDescriptor>();
264  vertex_descriptor->SetStageInputs(VS::kAllShaderStageInputs,
265  VS::kInterleavedBufferLayout);
266 
267  desc.SetVertexDescriptor(std::move(vertex_descriptor));
268  ColorAttachmentDescriptor color0;
269  color0.format = GetContext()->GetCapabilities()->GetDefaultColorFormat();
270  StencilAttachmentDescriptor stencil0;
271  stencil0.stencil_compare = CompareFunction::kEqual;
272  desc.SetColorAttachmentDescriptor(0u, color0);
273  desc.SetStencilAttachmentDescriptors(stencil0);
274  const auto stencil_fmt =
275  GetContext()->GetCapabilities()->GetDefaultStencilFormat();
276  desc.SetStencilPixelFormat(stencil_fmt);
277  auto pipeline = GetContext()->GetPipelineLibrary()->GetPipeline(desc).Get();
278  ASSERT_NE(pipeline, nullptr);
279 }

References impeller::PipelineDescriptor::AddStageEntrypoint(), impeller::ColorAttachmentDescriptor::format, impeller::kEqual, impeller::kFragment, 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() [368/384]

impeller::testing::TEST_P ( RuntimeStageTest  ,
CanReadUniforms   
)

Definition at line 61 of file runtime_stage_unittests.cc.

61  {
62  if (!BackendSupportsFragmentProgram()) {
63  GTEST_SKIP_("This backend doesn't support runtime effects.");
64  }
65 
66  const std::shared_ptr<fml::Mapping> fixture =
67  flutter::testing::OpenFixtureAsMapping("ink_sparkle.frag.iplr");
68  ASSERT_TRUE(fixture);
69  ASSERT_GT(fixture->GetSize(), 0u);
70  auto stages = RuntimeStage::DecodeRuntimeStages(fixture);
71  auto stage = stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
72 
73  ASSERT_TRUE(stage->IsValid());
74  ASSERT_EQ(stage->GetUniforms().size(), 17u);
75  {
76  auto uni = stage->GetUniform("u_color");
77  ASSERT_NE(uni, nullptr);
78  ASSERT_EQ(uni->dimensions.rows, 4u);
79  ASSERT_EQ(uni->dimensions.cols, 1u);
80  ASSERT_EQ(uni->location, 0u);
81  ASSERT_EQ(uni->type, RuntimeUniformType::kFloat);
82  }
83  {
84  auto uni = stage->GetUniform("u_alpha");
85  ASSERT_NE(uni, nullptr);
86  ASSERT_EQ(uni->dimensions.rows, 1u);
87  ASSERT_EQ(uni->dimensions.cols, 1u);
88  ASSERT_EQ(uni->location, 1u);
89  ASSERT_EQ(uni->type, RuntimeUniformType::kFloat);
90  }
91  {
92  auto uni = stage->GetUniform("u_sparkle_color");
93  ASSERT_NE(uni, nullptr);
94  ASSERT_EQ(uni->dimensions.rows, 4u);
95  ASSERT_EQ(uni->dimensions.cols, 1u);
96  ASSERT_EQ(uni->location, 2u);
97  ASSERT_EQ(uni->type, RuntimeUniformType::kFloat);
98  }
99  {
100  auto uni = stage->GetUniform("u_sparkle_alpha");
101  ASSERT_NE(uni, nullptr);
102  ASSERT_EQ(uni->dimensions.rows, 1u);
103  ASSERT_EQ(uni->dimensions.cols, 1u);
104  ASSERT_EQ(uni->location, 3u);
105  ASSERT_EQ(uni->type, RuntimeUniformType::kFloat);
106  }
107  {
108  auto uni = stage->GetUniform("u_blur");
109  ASSERT_NE(uni, nullptr);
110  ASSERT_EQ(uni->dimensions.rows, 1u);
111  ASSERT_EQ(uni->dimensions.cols, 1u);
112  ASSERT_EQ(uni->location, 4u);
113  ASSERT_EQ(uni->type, RuntimeUniformType::kFloat);
114  }
115  {
116  auto uni = stage->GetUniform("u_radius_scale");
117  ASSERT_NE(uni, nullptr);
118  ASSERT_EQ(uni->dimensions.rows, 1u);
119  ASSERT_EQ(uni->dimensions.cols, 1u);
120  ASSERT_EQ(uni->location, 6u);
121  ASSERT_EQ(uni->type, RuntimeUniformType::kFloat);
122  }
123  {
124  auto uni = stage->GetUniform("u_max_radius");
125  ASSERT_NE(uni, nullptr);
126  ASSERT_EQ(uni->dimensions.rows, 1u);
127  ASSERT_EQ(uni->dimensions.cols, 1u);
128  ASSERT_EQ(uni->location, 7u);
129  ASSERT_EQ(uni->type, RuntimeUniformType::kFloat);
130  }
131  {
132  auto uni = stage->GetUniform("u_resolution_scale");
133  ASSERT_NE(uni, nullptr);
134  ASSERT_EQ(uni->dimensions.rows, 2u);
135  ASSERT_EQ(uni->dimensions.cols, 1u);
136  ASSERT_EQ(uni->location, 8u);
137  ASSERT_EQ(uni->type, RuntimeUniformType::kFloat);
138  }
139  {
140  auto uni = stage->GetUniform("u_noise_scale");
141  ASSERT_NE(uni, nullptr);
142  ASSERT_EQ(uni->dimensions.rows, 2u);
143  ASSERT_EQ(uni->dimensions.cols, 1u);
144  ASSERT_EQ(uni->location, 9u);
145  ASSERT_EQ(uni->type, RuntimeUniformType::kFloat);
146  }
147  {
148  auto uni = stage->GetUniform("u_noise_phase");
149  ASSERT_NE(uni, nullptr);
150  ASSERT_EQ(uni->dimensions.rows, 1u);
151  ASSERT_EQ(uni->dimensions.cols, 1u);
152  ASSERT_EQ(uni->location, 10u);
153  ASSERT_EQ(uni->type, RuntimeUniformType::kFloat);
154  }
155 
156  {
157  auto uni = stage->GetUniform("u_circle1");
158  ASSERT_NE(uni, nullptr);
159  ASSERT_EQ(uni->dimensions.rows, 2u);
160  ASSERT_EQ(uni->dimensions.cols, 1u);
161  ASSERT_EQ(uni->location, 11u);
162  ASSERT_EQ(uni->type, RuntimeUniformType::kFloat);
163  }
164  {
165  auto uni = stage->GetUniform("u_circle2");
166  ASSERT_NE(uni, nullptr);
167  ASSERT_EQ(uni->dimensions.rows, 2u);
168  ASSERT_EQ(uni->dimensions.cols, 1u);
169  ASSERT_EQ(uni->location, 12u);
170  ASSERT_EQ(uni->type, RuntimeUniformType::kFloat);
171  }
172  {
173  auto uni = stage->GetUniform("u_circle3");
174  ASSERT_NE(uni, nullptr);
175  ASSERT_EQ(uni->dimensions.rows, 2u);
176  ASSERT_EQ(uni->dimensions.cols, 1u);
177  ASSERT_EQ(uni->location, 13u);
178  ASSERT_EQ(uni->type, RuntimeUniformType::kFloat);
179  }
180  {
181  auto uni = stage->GetUniform("u_rotation1");
182  ASSERT_NE(uni, nullptr);
183  ASSERT_EQ(uni->dimensions.rows, 2u);
184  ASSERT_EQ(uni->dimensions.cols, 1u);
185  ASSERT_EQ(uni->location, 14u);
186  ASSERT_EQ(uni->type, RuntimeUniformType::kFloat);
187  }
188  {
189  auto uni = stage->GetUniform("u_rotation2");
190  ASSERT_NE(uni, nullptr);
191  ASSERT_EQ(uni->dimensions.rows, 2u);
192  ASSERT_EQ(uni->dimensions.cols, 1u);
193  ASSERT_EQ(uni->location, 15u);
194  ASSERT_EQ(uni->type, RuntimeUniformType::kFloat);
195  }
196  {
197  auto uni = stage->GetUniform("u_rotation3");
198  ASSERT_NE(uni, nullptr);
199  ASSERT_EQ(uni->dimensions.rows, 2u);
200  ASSERT_EQ(uni->dimensions.cols, 1u);
201  ASSERT_EQ(uni->location, 16u);
202  ASSERT_EQ(uni->type, RuntimeUniformType::kFloat);
203  }
204 }

References impeller::RuntimeStage::DecodeRuntimeStages(), impeller::kFloat, and impeller::PlaygroundBackendToRuntimeStageBackend().

◆ TEST_P() [369/384]

impeller::testing::TEST_P ( RuntimeStageTest  ,
CanReadValidBlob   
)

Definition at line 27 of file runtime_stage_unittests.cc.

27  {
28  if (!BackendSupportsFragmentProgram()) {
29  GTEST_SKIP_("This backend doesn't support runtime effects.");
30  }
31 
32  const std::shared_ptr<fml::Mapping> fixture =
33  flutter::testing::OpenFixtureAsMapping("ink_sparkle.frag.iplr");
34  ASSERT_TRUE(fixture);
35  ASSERT_GT(fixture->GetSize(), 0u);
36  auto stages = RuntimeStage::DecodeRuntimeStages(fixture);
37  auto stage = stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
38  ASSERT_TRUE(stage->IsValid());
39  ASSERT_EQ(stage->GetShaderStage(), RuntimeShaderStage::kFragment);
40 }

References impeller::RuntimeStage::DecodeRuntimeStages(), impeller::kFragment, and impeller::PlaygroundBackendToRuntimeStageBackend().

◆ TEST_P() [370/384]

impeller::testing::TEST_P ( RuntimeStageTest  ,
CanRegisterStage   
)

Definition at line 206 of file runtime_stage_unittests.cc.

206  {
207  if (!BackendSupportsFragmentProgram()) {
208  GTEST_SKIP_("This backend doesn't support runtime effects.");
209  }
210 
211  const std::shared_ptr<fml::Mapping> fixture =
212  flutter::testing::OpenFixtureAsMapping("ink_sparkle.frag.iplr");
213  ASSERT_TRUE(fixture);
214  ASSERT_GT(fixture->GetSize(), 0u);
215  auto stages = RuntimeStage::DecodeRuntimeStages(fixture);
216  auto stage = stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
217  ASSERT_TRUE(stage->IsValid());
218  std::promise<bool> registration;
219  auto future = registration.get_future();
220  auto library = GetContext()->GetShaderLibrary();
221  library->RegisterFunction(
222  stage->GetEntrypoint(), //
223  ToShaderStage(stage->GetShaderStage()), //
224  stage->GetCodeMapping(), //
225  fml::MakeCopyable([reg = std::move(registration)](bool result) mutable {
226  reg.set_value(result);
227  }));
228  ASSERT_TRUE(future.get());
229  {
230  auto function =
231  library->GetFunction(stage->GetEntrypoint(), ShaderStage::kFragment);
232  ASSERT_NE(function, nullptr);
233  }
234 
235  // Check if unregistering works.
236 
237  library->UnregisterFunction(stage->GetEntrypoint(), ShaderStage::kFragment);
238  {
239  auto function =
240  library->GetFunction(stage->GetEntrypoint(), ShaderStage::kFragment);
241  ASSERT_EQ(function, nullptr);
242  }
243 }

References impeller::RuntimeStage::DecodeRuntimeStages(), impeller::kFragment, impeller::PlaygroundBackendToRuntimeStageBackend(), and impeller::ToShaderStage().

◆ TEST_P() [371/384]

impeller::testing::TEST_P ( RuntimeStageTest  ,
CanRejectInvalidBlob   
)

Definition at line 42 of file runtime_stage_unittests.cc.

42  {
43  if (!BackendSupportsFragmentProgram()) {
44  GTEST_SKIP_("This backend doesn't support runtime effects.");
45  }
46 
47  ScopedValidationDisable disable_validation;
48  const std::shared_ptr<fml::Mapping> fixture =
49  flutter::testing::OpenFixtureAsMapping("ink_sparkle.frag.iplr");
50  ASSERT_TRUE(fixture);
51  auto junk_allocation = std::make_shared<Allocation>();
52  ASSERT_TRUE(junk_allocation->Truncate(fixture->GetSize(), false));
53  // Not meant to be secure. Just reject obviously bad blobs using magic
54  // numbers.
55  ::memset(junk_allocation->GetBuffer(), 127, junk_allocation->GetLength());
56  auto stages = RuntimeStage::DecodeRuntimeStages(
57  CreateMappingFromAllocation(junk_allocation));
58  ASSERT_FALSE(stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())]);
59 }

References impeller::CreateMappingFromAllocation(), impeller::RuntimeStage::DecodeRuntimeStages(), and impeller::PlaygroundBackendToRuntimeStageBackend().

◆ TEST_P() [372/384]

impeller::testing::TEST_P ( RuntimeStageTest  ,
ContainsExpectedShaderTypes   
)

Definition at line 281 of file runtime_stage_unittests.cc.

281  {
282  auto stages = OpenAssetAsRuntimeStage("ink_sparkle.frag.iplr");
283  // Right now, SkSL gets implicitly bundled regardless of what the build rule
284  // for this test requested. After
285  // https://github.com/flutter/flutter/issues/138919, this may require a build
286  // rule change or a new test.
287  EXPECT_TRUE(stages[RuntimeStageBackend::kSkSL]);
288 
289  EXPECT_TRUE(stages[RuntimeStageBackend::kOpenGLES]);
290  EXPECT_TRUE(stages[RuntimeStageBackend::kMetal]);
291  // TODO(dnfield): Flip this when
292  // https://github.com/flutter/flutter/issues/122823 is fixed.
293  EXPECT_FALSE(stages[RuntimeStageBackend::kVulkan]);
294 }

References impeller::kMetal, impeller::kOpenGLES, impeller::kSkSL, and impeller::kVulkan.

◆ TEST_P() [373/384]

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() [374/384]

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() [375/384]

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() [376/384]

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() [377/384]

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() [378/384]

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() [379/384]

impeller::testing::TEST_P ( TypographerTest  ,
GlyphAtlasTextureIsRecycledWhenContentsAreRecreated   
)

Definition at line 341 of file typographer_unittests.cc.

341  {
342  auto context = TypographerContextSkia::Make();
343  auto atlas_context = context->CreateGlyphAtlasContext();
344  ASSERT_TRUE(context && context->IsValid());
345  SkFont sk_font = flutter::testing::CreateTestFontOfSize(12);
346  auto blob = SkTextBlob::MakeFromString("ABCDEFGHIJKLMNOPQRSTUVQXYZ123456789",
347  sk_font);
348  ASSERT_TRUE(blob);
349  auto atlas = CreateGlyphAtlas(
350  *GetContext(), context.get(), GlyphAtlas::Type::kColorBitmap, 32.0f,
351  atlas_context, *MakeTextFrameFromTextBlobSkia(blob));
352  auto old_packer = atlas_context->GetRectPacker();
353 
354  ASSERT_NE(atlas, nullptr);
355  ASSERT_NE(atlas->GetTexture(), nullptr);
356  ASSERT_EQ(atlas, atlas_context->GetGlyphAtlas());
357 
358  auto* first_texture = atlas->GetTexture().get();
359 
360  // Now create a new glyph atlas with a completely different textblob.
361  // everything should be different except for the underlying atlas texture.
362 
363  auto blob2 = SkTextBlob::MakeFromString("abcdefghijklmnopqrstuvwxyz123456789",
364  sk_font);
365  auto next_atlas = CreateGlyphAtlas(
366  *GetContext(), context.get(), GlyphAtlas::Type::kColorBitmap, 32.0f,
367  atlas_context, *MakeTextFrameFromTextBlobSkia(blob2));
368  ASSERT_NE(atlas, next_atlas);
369  auto* second_texture = next_atlas->GetTexture().get();
370 
371  auto new_packer = atlas_context->GetRectPacker();
372 
373  ASSERT_EQ(second_texture, first_texture);
374  ASSERT_NE(old_packer, new_packer);
375 }

References CreateGlyphAtlas(), impeller::GlyphAtlas::kColorBitmap, impeller::TypographerContextSkia::Make(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [380/384]

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  std::move(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() [381/384]

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() [382/384]

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 alpha 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() [383/384]

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() [384/384]

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 824 of file aiks_unittests.cc.

Referenced by TEST_P().

◆ LastSample

int64_t impeller::testing::LastSample = 0
static

Definition at line 20 of file archivist_unittests.cc.

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:32
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
DEBUG_COMMAND_INFO
#define DEBUG_COMMAND_INFO(obj, arg)
Definition: command.h:28
impeller::kPreConcat
@ kPreConcat
Definition: canvas_recorder.h:28
impeller::kDrawImage
@ kDrawImage
Definition: canvas_recorder.h:40
impeller::testing::CompareFunctionUI
static const CompareFunctionUIData & CompareFunctionUI()
Definition: renderer_unittests.cc:1109
impeller::BlendModeToString
const char * BlendModeToString(BlendMode blend_mode)
Definition: color.cc:47
impeller::kClipPath
@ kClipPath
Definition: canvas_recorder.h:42
impeller::TextureUsageMask
uint64_t TextureUsageMask
Definition: formats.h:295
impeller::TPoint::y
Type y
Definition: point.h:26
impeller::Scalar
float Scalar
Definition: scalar.h:18
impeller::TPoint::Ceil
constexpr TPoint Ceil() const
Definition: point.h:191
impeller::testing::CompareFunctionUIData::IndexOf
int IndexOf(CompareFunction func) const
Definition: renderer_unittests.cc:1092
impeller::testing::CanRenderSweepGradientWithDithering
static void CanRenderSweepGradientWithDithering(AiksTest *aiks_test, bool use_dithering)
Definition: aiks_gradient_unittests.cc:140
impeller::kConcat
@ kConcat
Definition: canvas_recorder.h:27
impeller::kDrawPicture
@ kDrawPicture
Definition: canvas_recorder.h:45
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::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:225
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:169
impeller::TPoint::Min
constexpr TPoint Min(const TPoint &p) const
Definition: point.h:181
impeller::ScaleSigma
Sigma ScaleSigma(Sigma sigma)
Definition: directional_gaussian_blur_filter_contents.cc:27
impeller::kRotate
@ kRotate
Definition: canvas_recorder.h:33
impeller::TPoint::Round
static constexpr TPoint Round(const TPoint< U > &other)
Definition: point.h:44
impeller::Vector2
Point Vector2
Definition: point.h:312
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:1000
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_PLAYGROUND_POINT
#define IMPELLER_PLAYGROUND_POINT(default_position, radius, color)
Definition: widgets.h:15
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:311
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:435
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
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:189
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:721
impeller::kPiOver2
constexpr float kPiOver2
Definition: constants.h:32
impeller::PixelFormat
PixelFormat
The Pixel formats supported by Impeller. The naming convention denotes the usage of the component,...
Definition: formats.h:94
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:38
impeller::kPhi
constexpr float kPhi
Definition: constants.h:53
impeller::kColor
@ kColor
Definition: geometry.h:36
impeller::testing::toColor
flutter::DlColor toColor(const float *components)
Definition: dl_unittests.cc:41
impeller::kDrawTextFrame
@ kDrawTextFrame
Definition: canvas_recorder.h:46
impeller::testing::CreateColorVertices
std::shared_ptr< VerticesGeometry > CreateColorVertices(const std::vector< Point > &vertices, const std::vector< Color > &colors)
Definition: vertices_contents_unittests.cc:25
impeller::kScale2
@ kScale2
Definition: canvas_recorder.h:30
impeller::Point
TPoint< Scalar > Point
Definition: point.h:308
impeller::k2Pi
constexpr float k2Pi
Definition: constants.h:29
impeller::Quad
std::array< Point, 4 > Quad
Definition: point.h:313
impeller::testing::CompareFunctionUIData::FunctionOf
CompareFunction FunctionOf(int index) const
Definition: renderer_unittests.cc:1102
impeller::testing::RGBToYUV
static Vector3 RGBToYUV(Vector3 rgb, YUVColorSpace yuv_color_space)
Definition: entity_unittests.cc:2033
impeller::MipFilter
MipFilter
Definition: formats.h:412
impeller::SPrintF
std::string SPrintF(const char *format,...)
Definition: strings.cc:12
impeller::testing::GetBlendModeSelection
static BlendModeSelection GetBlendModeSelection()
Definition: aiks_unittests.cc:1007
impeller::IPoint32
TPoint< int32_t > IPoint32
Definition: point.h:310
impeller::ScalarToHalf
constexpr InternalHalf ScalarToHalf(Scalar f)
Convert a scalar to a half precision float.
Definition: half.h:31
impeller::kDrawRect
@ kDrawRect
Definition: canvas_recorder.h:36
impeller::TPoint::Max
constexpr TPoint Max(const TPoint &p) const
Definition: point.h:185
impeller::testing::CanRenderRadialGradientWithDithering
static void CanRenderRadialGradientWithDithering(AiksTest *aiks_test, bool use_dithering)
Definition: aiks_gradient_unittests.cc:113
impeller::kSkew
@ kSkew
Definition: canvas_recorder.h:32
impeller::kClipRRect
@ kClipRRect
Definition: canvas_recorder.h:44
impeller::MinMagFilter
MinMagFilter
Definition: formats.h:404
impeller::kDrawImageRect
@ kDrawImageRect
Definition: canvas_recorder.h:41
impeller::testing::CanRenderLinearGradientWithDithering
static void CanRenderLinearGradientWithDithering(AiksTest *aiks_test, bool use_dithering)
Definition: aiks_gradient_unittests.cc:85
impeller::testing::CreateTestYUVTextures
static std::vector< std::shared_ptr< Texture > > CreateTestYUVTextures(Context *context, YUVColorSpace yuv_color_space)
Definition: entity_unittests.cc:2050
_BLEND_MODE_NAME_CHECK
#define _BLEND_MODE_NAME_CHECK(blend_mode)
Definition: geometry_unittests.cc:1447
impeller::Rect
TRect< Scalar > Rect
Definition: rect.h:488
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::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::kTransform
@ kTransform
Definition: canvas_recorder.h:26
impeller::kDrawAtlas
@ kDrawAtlas
Definition: canvas_recorder.h:48
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::testing::CreatePassWithRectPath
auto CreatePassWithRectPath(Rect rect, std::optional< Rect > bounds_hint, bool collapse=false)
Definition: entity_unittests.cc:105
impeller::IRect
TRect< int64_t > IRect
Definition: rect.h:489
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:67
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:684
FLT_FORWARD
#define FLT_FORWARD(mock, real, method)
Definition: aiks_unittests.cc:3601
impeller::LineTo
void LineTo(PathBuilder *builder, Scalar x, Scalar y)
Definition: tessellator.cc:22
impeller::Join
Join
Definition: path.h:24
RectNear
inline ::testing::AssertionResult RectNear(impeller::Rect a, impeller::Rect b)
Definition: geometry_asserts.h:56
impeller::kDrawPoints
@ kDrawPoints
Definition: canvas_recorder.h:39
impeller::IPoint
TPoint< int64_t > IPoint
Definition: point.h:309
ASSERT_VECTOR3_NEAR
#define ASSERT_VECTOR3_NEAR(a, b)
Definition: geometry_asserts.h:161
impeller::testing::kFontFixture
static constexpr std::string_view kFontFixture
Definition: aiks_unittests.cc:824
impeller::ScalarNearlyEqual
constexpr bool ScalarNearlyEqual(Scalar x, Scalar y, Scalar tolerance=kEhCloseEnough)
Definition: scalar.h:30
impeller::YUVColorSpace
YUVColorSpace
Definition: color.h:55
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:195
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
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:47
impeller::TPoint::Normalize
constexpr TPoint Normalize() const
Definition: point.h:203
impeller::kDrawPath
@ kDrawPath
Definition: canvas_recorder.h:34
impeller::kDrawRRect
@ kDrawRRect
Definition: canvas_recorder.h:37
ASSERT_COLOR_BUFFER_NEAR
#define ASSERT_COLOR_BUFFER_NEAR(a, b)
Definition: geometry_asserts.h:165
IMPELLER_PLAYGROUND_LINE
#define IMPELLER_PLAYGROUND_LINE(default_position_a, default_position_b, radius, color_a, color_b)
Definition: widgets.h:56
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:43
impeller::Cap
Cap
Definition: path.h:18
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::kRestoreToCount
@ kRestoreToCount
Definition: canvas_recorder.h:24